lcd: unify extern driver struct and flag [2/2]

PD#173257: lcd: unify extern driver struct and flag
include:
1.lcd_extern
2.mipi
3.bl_extern
4.bl_ldim

Change-Id: Ibfd81423151bcefe5ca1c85d442ce029af5b54b7
Signed-off-by: Evoke Zhang <evoke.zhang@amlogic.com>
This commit is contained in:
Evoke Zhang
2018-09-04 13:34:38 +08:00
parent ffd89f6c33
commit 783b7b4e7d
52 changed files with 3606 additions and 1765 deletions

View File

@@ -14627,8 +14627,12 @@ F: Documentation/devicetree/bindings/amlogic/input/pca9557_keypad.txt
F: drivers/amlogic/input/keyboard/pca9557_keypad.c
F: Documentation/devicetree/bindings/is31fl3236a.txt
AMLOGIC LCD EXTERN DRIVER
F: drivers/amlogic/media/vout/backlight/bl_extern/bl_ext_default.c
F: drivers/amlogic/media/vout/lcd/lcd_extern/i2c_ANX6862_7911.c
F: include/linux/amlogic/media/vout/lcd/aml_lcd.h
AMLOGIC TL1 CLOCK DRIVERS
M: Jian Hu <jian.hu@amlogic.com>
F: include/dt-bindings/clock/amlogic,tl1-clkc.h
F: drivers/amlogic/clk/tl1/*

View File

@@ -18,7 +18,6 @@
/ {
lcd {
compatible = "amlogic, lcd-txl";
dev_name = "lcd";
mode = "tv";
status = "okay";
fr_auto_policy = <1>; /* 0=disable, 1=60/50hz, 2=60/50/48hz */
@@ -416,7 +415,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
key_valid = <1>;
i2c_bus = "i2c_bus_c";
@@ -440,27 +438,29 @@
cmd_size = <0xff>; /*dynamic cmd_size*/
/* init on/off:
* fixed cmd_size: (type, value..., delay);
* fixed cmd_size: (type, value...);
* cmd_size include all data.
* dynamic cmd_size: (type, cmd_size, value..., delay);
* cmd_size include value+delay.
* dynamic cmd_size: (type, cmd_size, value...);
* cmd_size include value.
*/
/* type: 0x00=cmd(bit[3:0]=1 for second_addr),
* 0xf0=gpio, 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level,
* fill 0x0 for no use
/* type: 0x00=cmd with delay(bit[3:0]=1 for address2),
* 0xc0=cmd(bit[3:0]=1 for address2),
* 0xf0=gpio,
* 0xfd=delay,
* 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level */
/* delay: unit ms */
init_on = <
0x00 8 0x20 0x01 0x02 0x00 0x40 0xFF 0x00 0
0x00 8 0x80 0x02 0x00 0x40 0x62 0x51 0x73 0
0x00 8 0x61 0x06 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00 0
0x00 8 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0x3D 0x02 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0xED 0x0D 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0x23 0x02 0x00 0x00 0x00 0x00 0x00 10
0xc0 7 0x20 0x01 0x02 0x00 0x40 0xFF 0x00
0xc0 7 0x80 0x02 0x00 0x40 0x62 0x51 0x73
0xc0 7 0x61 0x06 0x00 0x00 0x00 0x00 0x00
0xc0 7 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00
0xc0 7 0x13 0x01 0x00 0x00 0x00 0x00 0x00
0xc0 7 0x3D 0x02 0x01 0x00 0x00 0x00 0x00
0xc0 7 0xED 0x0D 0x01 0x00 0x00 0x00 0x00
0xc0 7 0x23 0x02 0x00 0x00 0x00 0x00 0x00
0xfd 1 10 /* delay 10ms */
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
@@ -470,13 +470,11 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
cmd_size = <9>;
};
};
backlight{
compatible = "amlogic, backlight-txl";
dev_name = "backlight";
status = "okay";
key_valid = <1>;
pinctrl-names = "pwm_on","pwm_vs_on",

View File

@@ -18,7 +18,6 @@
/ {
lcd {
compatible = "amlogic, lcd-txlx";
dev_name = "lcd";
mode = "tv";
status = "okay";
fr_auto_policy = <1>; /* 0=disable, 1=60/50hz, 2=60/50/48hz */
@@ -454,7 +453,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
key_valid = <1>;
i2c_bus = "i2c_bus_c";
@@ -474,31 +472,33 @@
status = "disabled";
type = <0>; /*0=i2c, 1=spi, 2=mipi*/
i2c_address = <0x1c>; /*7bit i2c_addr*/
i2c_second_address = <0xff>;
i2c_address2 = <0xff>;
cmd_size = <0xff>; /*dynamic cmd_size*/
/* init on/off:
* fixed cmd_size: (type, value..., delay);
* fixed cmd_size: (type, value...);
* cmd_size include all data.
* dynamic cmd_size: (type, cmd_size, value..., delay);
* cmd_size include value+delay.
* dynamic cmd_size: (type, cmd_size, value...);
* cmd_size include value.
*/
/* type: 0x00=cmd(bit[3:0]=1 for second_addr),
* 0xf0=gpio, 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level,
* fill 0x0 for no use
/* type: 0x00=cmd with delay(bit[3:0]=1 for address2),
* 0xc0=cmd(bit[3:0]=1 for address2),
* 0xf0=gpio,
* 0xfd=delay,
* 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level */
/* delay: unit ms */
init_on = <
0x00 8 0x20 0x01 0x02 0x00 0x40 0xFF 0x00 0
0x00 8 0x80 0x02 0x00 0x40 0x62 0x51 0x73 0
0x00 8 0x61 0x06 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00 0
0x00 8 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0x3D 0x02 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0xED 0x0D 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0x23 0x02 0x00 0x00 0x00 0x00 0x00 10
0xc0 7 0x20 0x01 0x02 0x00 0x40 0xFF 0x00
0xc0 7 0x80 0x02 0x00 0x40 0x62 0x51 0x73
0xc0 7 0x61 0x06 0x00 0x00 0x00 0x00 0x00
0xc0 7 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00
0xc0 7 0x13 0x01 0x00 0x00 0x00 0x00 0x00
0xc0 7 0x3D 0x02 0x01 0x00 0x00 0x00 0x00
0xc0 7 0xED 0x0D 0x01 0x00 0x00 0x00 0x00
0xc0 7 0x23 0x02 0x00 0x00 0x00 0x00 0x00
0xfd 1 10 /* delay 10ms */
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
@@ -508,13 +508,60 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
cmd_size = <9>;
};
extern_2{
index = <2>;
extern_name = "i2c_ANX6862_7911";
status = "okay";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x20>; /* 7bit i2c address */
i2c_address2 = <0x74>; /* 7bit i2c address */
cmd_size = <0xff>;
init_on = <
0xc0 2 0x01 0x2b
0xc0 2 0x02 0x05
0xc0 2 0x03 0x00
0xc0 2 0x04 0x00
0xc0 2 0x05 0x0c
0xc0 2 0x06 0x04
0xc0 2 0x07 0x21
0xc0 2 0x08 0x0f
0xc0 2 0x09 0x04
0xc0 2 0x0a 0x00
0xc0 2 0x0b 0x04
0xc0 2 0xff 0x00
0xfd 1 100 /* delay 100ms */
0xc1 2 0x01 0xca
0xc1 2 0x02 0x3b
0xc1 2 0x03 0x33
0xc1 2 0x04 0x05
0xc1 2 0x05 0x2c
0xc1 2 0x06 0xf2
0xc1 2 0x07 0x9c
0xc1 2 0x08 0x1b
0xc1 2 0x09 0x82
0xc1 2 0x0a 0x3d
0xc1 2 0x0b 0x20
0xc1 2 0x0c 0x11
0xc1 2 0x0d 0xc4
0xc1 2 0x0e 0x1a
0xc1 2 0x0f 0x31
0xc1 2 0x10 0x4c
0xc1 2 0x11 0x12
0xc1 2 0x12 0x90
0xc1 2 0x13 0xf7
0xc1 2 0x14 0x0c
0xc1 2 0x15 0x20
0xc1 2 0x16 0x13
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
};
backlight{
compatible = "amlogic, backlight-txlx";
dev_name = "backlight";
status = "okay";
key_valid = <1>;
pinctrl-names = "pwm_on","pwm_vs_on",
@@ -678,7 +725,6 @@
local_dimming_device {
compatible = "amlogic, ldim_dev";
dev_name = "ldim_dev";
status = "okay";
pinctrl-names = "ldim_pwm",
"ldim_pwm_vs",
@@ -745,30 +791,32 @@
dim_max_min = <0xfff 0x7f>; /* dim_max, dim_min */
ldim_region_mapping = <0 1 2 3 4 5 6 7 8 9>;
cmd_size = <4>;
/* init: (type, data..., delay),
* must match cmd_size for every group
cmd_size = <0xff>;
/* init: (type, data...) */
/* type: 0x00=cmd with delay,
* 0xc0=cmd,
* 0xfd=delay,
* 0xff=ending
*/
/* type: 0x00=cmd, 0xff=ending*/
/* data: spi data, fill 0x0 for no use */
/* delay: unit ms */
init_on = <
0x00 0x23 0x03 0x00
0x00 0x24 0xff 0x00
0x00 0x25 0x00 0x00
0x00 0x26 0x00 0x00
0x00 0x27 0x60 0x00
0x00 0x29 0x00 0x00
0x00 0x2a 0x00 0x00
0x00 0x2b 0x00 0x00
0x00 0x2c 0x73 0x00
0x00 0x2d 0x37 0x00
0x00 0x31 0x93 0x00
0x00 0x32 0x0f 0x00
0x00 0x33 0xff 0x00
0x00 0x34 0xc8 0x00
0x00 0x35 0xbf 0x00
0xff 0x00 0x00 0x00>;
0xc0 2 0x23 0x03
0xc0 2 0x24 0xff
0xc0 2 0x25 0x00
0xc0 2 0x26 0x00
0xc0 2 0x27 0x60
0xc0 2 0x29 0x00
0xc0 2 0x2a 0x00
0xc0 2 0x2b 0x00
0xc0 2 0x2c 0x73
0xc0 2 0x2d 0x37
0xc0 2 0x31 0x93
0xc0 2 0x32 0x0f
0xc0 2 0x33 0xff
0xc0 2 0x34 0xc8
0xc0 2 0x35 0xbf
0xff 0>;
};
};

View File

@@ -1483,6 +1483,20 @@
reg = <0x1c>;
status = "okay";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX6862";
reg = <0x20>;
status = "okay";
};
lcd_extern_i2c2: lcd_extern_i2c@2 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX7911";
reg = <0x74>;
status = "okay";
};
};
&i2c1 {

View File

@@ -1488,6 +1488,20 @@
reg = <0x1c>;
status = "okay";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX6862";
reg = <0x20>;
status = "okay";
};
lcd_extern_i2c2: lcd_extern_i2c@2 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX7911";
reg = <0x74>;
status = "okay";
};
};
&i2c1 {

View File

@@ -287,6 +287,7 @@ CONFIG_AMLOGIC_LCD=y
CONFIG_AMLOGIC_LCD_TV=y
CONFIG_AMLOGIC_LCD_TABLET=y
CONFIG_AMLOGIC_LCD_EXTERN=y
CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6862_7911=y
CONFIG_AMLOGIC_BACKLIGHT=y
CONFIG_AMLOGIC_BL_EXTERN=y
CONFIG_AMLOGIC_BL_EXTERN_I2C_LP8556=y

View File

@@ -749,11 +749,18 @@
dev_name = "lp8556";
};
lcd_extern_i2c {
compatible = "amlogic, lcd_i2c_T5800Q";
lcd_extern_i2c0: lcd_extern_i2c@0 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_LT8912_0";
reg = <0x48>;
status = "disabled";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_LT8912_1";
reg = <0x49>;
status = "disabled";
reg = <0x1c>; /*reg_address for i2c_T5800Q*/
dev_name = "i2c_T5800Q";
};
};

View File

@@ -697,11 +697,19 @@
reg = <0x2c>; /*reg_address for lp8556*/
dev_name = "lp8556";
};
lcd_extern_i2c {
compatible = "amlogic, lcd_i2c_T5800Q";
lcd_extern_i2c0: lcd_extern_i2c@0 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_LT8912_0";
reg = <0x48>;
status = "disabled";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_LT8912_1";
reg = <0x49>;
status = "disabled";
reg = <0x1c>; /*reg_address for i2c_T5800Q*/
dev_name = "i2c_T5800Q";
};
};

View File

@@ -748,6 +748,20 @@
reg-data-type = <1>;
link-device = <&phycsi>;
};
lcd_extern_i2c0: lcd_extern_i2c@0 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_LT8912_0";
reg = <0x48>;
status = "disabled";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_LT8912_1";
reg = <0x49>;
status = "disabled";
};
};
&isp {

View File

@@ -18,7 +18,6 @@
/ {
lcd{
compatible = "amlogic, lcd-axg";
dev_name = "lcd";
mode = "tablet";
status = "okay";
key_valid = <0>;
@@ -75,15 +74,15 @@
/* dsi_init: data_type, num, data... */
dsi_init_on = <0x05 1 0x11
0xff 20 /*delay(ms)*/
0xfd 1 20 /*delay(ms)*/
0x05 1 0x29
0xff 20 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 20 /*delay(ms)*/
0xff 0>; /*ending*/
dsi_init_off = <0x05 1 0x28
0xff 10 /*delay(ms)*/
0xfd 1 10 /*delay(ms)*/
0x05 1 0x10
0xff 10 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 10 /*delay(ms)*/
0xff 0>; /*ending*/
extern_init = <0xff>; /*0xff for invalid*/
/* power step: type, index, value, delay(ms) */
@@ -127,8 +126,8 @@
0xf0 3 0 1 30 /* reset high, delay 30ms */
0xf0 3 0 0 10 /* reset low, delay 10ms */
0xf0 3 0 1 30 /* reset high, delay 30ms */
0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <1>;
/* power step: type,index,value,delay(ms) */
@@ -167,8 +166,8 @@
0 /*clk_always_hs(0=disable,1=enable)*/
0>; /*phy_switch(0=auto,1=standard,2=slow)*/
/* dsi_init: data_type, num, data... */
dsi_init_on = <0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
dsi_init_on = <0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <3>;
/* power step: type,index,value,delay(ms) */
@@ -209,8 +208,8 @@
1 /*clk_always_hs(0=disable,1=enable)*/
0>; /*phy_switch(0=auto,1=standard,2=slow)*/
/* dsi_init: data_type, num, data... */
dsi_init_on = <0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
dsi_init_on = <0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <2>;
/* power step: type,index,value,delay(ms) */
@@ -228,7 +227,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
i2c_bus = "i2c_bus_1";
key_valid = <0>;
@@ -240,17 +238,17 @@
type = <2>; /* 0=i2c, 1=spi, 2=mipi */
cmd_size = <0xff>;
init_on = <
0xff 10
0xfd 1 10
0x05 1 0x11
0xff 120 /* delay 120ms */
0xfd 1 120 /* delay 120ms */
0x05 1 0x29
0xff 0xff>; /*ending*/
0xff 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_1{
@@ -260,14 +258,14 @@
type = <2>; /* 0=i2c, 1=spi, 2=mipi */
cmd_size = <0xff>;
init_on = <
0xff 10
0xfd 1 10
0x15 2 0x62 0x01
0x39 5 0xff 0xaa 0x55 0x25 0x01
0x15 2 0xfc 0x08
0xff 1 /* delay */
0xfd 1 1 /* delay */
0x15 2 0xfc 0x00
0x39 5 0xff 0xaa 0x55 0x25 0x00
0xff 20 /* delay */
0xfd 1 20 /* delay */
0x39 6 0xf0 0x55 0xaa 0x52 0x08 0x00
0x39 3 0xb1 0x68 0x41
0x15 2 0xb5 0x88
@@ -396,16 +394,16 @@
0x15 2 0x53 0x2C
0x15 2 0x55 0x03
0x05 1 0x11
0xff 120 /* delay 120ms */
0xfd 1 120 /* delay 120ms */
0x05 1 0x29
0xff 130 /* delay 130ms */
0xFF 0xFF>; /*ending*/
0xfd 1 130 /* delay 130ms */
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_2{
@@ -415,7 +413,7 @@
type = <2>; /* 0=i2c, 1=spi, 2=mipi */
init_on = <
0x13 1 0x11
0xff 200
0xfd 1 200
0x29 6 0xff 0x77 0x01 0x00 0x00 0x10
0x29 3 0xc0 0xe9 0x03
0x29 3 0xc1 0x11 0x02
@@ -439,7 +437,7 @@
0x23 2 0xc2 0x78
0x23 2 0xd0 0x88
0xff 100
0xfd 1 100
0x29 4 0xe0 0x00 0x00 0x02
0x29 12 0xe1 0x08 0x00 0x0a 0x00 0x07
0x00 0x09 0x00 0x00 0x33 0x33
@@ -461,17 +459,17 @@
0xff 0xff 0xff 0xff 0xff 0xff 0x10
0x45 0x67 0x98 0xba
0xff 10
0xfd 1 10
0x29 6 0xff 0x77 0x01 0x00 0x00 0x00
0x13 1 0x29
0xff 200
0xff 0xff>; /*ending*/
0xfd 1 200
0xff 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_3{
@@ -483,19 +481,19 @@
init_on = <
0x29 5 0xFF 0xAA 0x55 0x25 0x01
0x23 2 0xFC 0x08
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0xFC 0x00
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0x6F 0x21
0x23 2 0xF7 0x01
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0x6F 0x21
0x23 2 0xF7 0x00
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0x6F 0x1A
0x23 2 0xF7 0x05
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x29 5 0xFF 0xAA 0x55 0x25 0x00
@@ -637,22 +635,21 @@
0x13 1 0x35
0x13 1 0x11
0xFF 120 /* delay(ms) */
0xfd 1 120 /* delay(ms) */
0x13 1 0x29
0xFF 20 /* delay(ms) */
0xFF 0xFF>; /*ending*/
0xfd 1 20 /* delay(ms) */
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
};
backlight{
compatible = "amlogic, backlight-axg";
dev_name = "backlight";
status = "okay";
key_valid = <0>;
pinctrl-names = "pwm_on","pwm_off";
@@ -711,7 +708,6 @@
bl_extern{
compatible = "amlogic, bl_extern";
dev_name = "bl_extern";
status = "disabled";
i2c_bus = "i2c_bus_3";

View File

@@ -18,7 +18,6 @@
/ {
lcd{
compatible = "amlogic, lcd-g12a";
dev_name = "lcd";
mode = "tablet";
status = "okay";
key_valid = <0>;
@@ -79,15 +78,15 @@
/* dsi_init: data_type, num, data... */
dsi_init_on = <0x05 1 0x11
0xff 20 /*delay(ms)*/
0xfd 1 20 /*delay(ms)*/
0x05 1 0x29
0xff 20 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 20 /*delay(ms)*/
0xff 0>; /*ending*/
dsi_init_off = <0x05 1 0x28
0xff 10 /*delay(ms)*/
0xfd 1 10 /*delay(ms)*/
0x05 1 0x10
0xff 10 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 10 /*delay(ms)*/
0xff 0>; /*ending*/
extern_init = <0xff>; /*0xff for invalid*/
/* power step: type, index, value, delay(ms) */
@@ -136,8 +135,8 @@
0xf0 3 0 0 10 /* reset low, delay 10ms */
0xf0 3 0 1 30 /* reset high, delay 30ms */
0xfc 2 0x04 3 /* check_reg, check_cnt */
0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <1>;
/* power step: type,index,value,delay(ms) */
@@ -184,8 +183,8 @@
0xf0 3 0 0 10 /* reset low, delay 10ms */
0xf0 3 0 1 30 /* reset high, delay 30ms */
0xfc 2 0x04 3 /* check_reg, check_cnt */
0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <2>;
/* power step: type,index,value,delay(ms) */
@@ -226,8 +225,8 @@
1 /*clk_always_hs(0=disable,1=enable)*/
0>; /*phy_switch(0=auto,1=standard,2=slow)*/
/* dsi_init: data_type, num, data... */
dsi_init_on = <0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
dsi_init_on = <0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <3>;
/* power step: type,index,value,delay(ms) */
@@ -273,15 +272,15 @@
/* dsi_init: data_type, num, data... */
dsi_init_on = <0x05 1 0x11
0xff 20 /*delay(ms)*/
0xfd 1 20 /*delay(ms)*/
0x05 1 0x29
0xff 20 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 20 /*delay(ms)*/
0xff 0>; /*ending*/
dsi_init_off = <0x05 1 0x28
0xff 10 /*delay(ms)*/
0xfd 1 10 /*delay(ms)*/
0x05 1 0x10
0xff 10 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 10 /*delay(ms)*/
0xff 0>; /*ending*/
extern_init = <0xff>; /*0xff for invalid*/
/* power step: type, index, value, delay(ms) */
@@ -330,8 +329,8 @@
0xf0 3 0 0 10 /* reset low, delay 10ms */
0xf0 3 0 1 30 /* reset high, delay 30ms */
0xfc 2 0x04 3 /* check_reg, check_cnt */
0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <4>;
/* power step: type,index,value,delay(ms) */
@@ -378,8 +377,8 @@
0xf0 3 0 0 10 /* reset low, delay 10ms */
0xf0 3 0 1 30 /* reset high, delay 30ms */
0xfc 2 0x04 3 /* check_reg, check_cnt */
0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <5>;
/* power step: type,index,value,delay(ms) */
@@ -398,7 +397,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
i2c_bus = "i2c_bus_0";
key_valid = <0>;
@@ -410,17 +408,17 @@
type = <2>; /* 0=i2c, 1=spi, 2=mipi */
cmd_size = <0xff>;
init_on = <
0xff 10
0xfd 1 10
0x05 1 0x11
0xff 120 /* delay 120ms */
0xfd 1 120 /* delay 120ms */
0x05 1 0x29
0xff 0xff>; /*ending*/
0xff 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_1{
@@ -430,14 +428,14 @@
type = <2>; /* 0=i2c, 1=spi, 2=mipi */
cmd_size = <0xff>;
init_on = <
0xff 10
0xfd 1 10
0x15 2 0x62 0x01
0x39 5 0xff 0xaa 0x55 0x25 0x01
0x15 2 0xfc 0x08
0xff 1 /* delay */
0xfd 1 1 /* delay */
0x15 2 0xfc 0x00
0x39 5 0xff 0xaa 0x55 0x25 0x00
0xff 20 /* delay */
0xfd 1 20 /* delay */
0x39 6 0xf0 0x55 0xaa 0x52 0x08 0x00
0x39 3 0xb1 0x68 0x41
0x15 2 0xb5 0x88
@@ -566,16 +564,16 @@
0x15 2 0x53 0x2C
0x15 2 0x55 0x03
0x05 1 0x11
0xff 120 /* delay 120ms */
0xfd 1 120 /* delay 120ms */
0x05 1 0x29
0xff 130 /* delay 130ms */
0xFF 0xFF>; /*ending*/
0xfd 1 130 /* delay 130ms */
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_2{
@@ -587,19 +585,19 @@
init_on = <
0x29 5 0xFF 0xAA 0x55 0x25 0x01
0x23 2 0xFC 0x08
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0xFC 0x00
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0x6F 0x21
0x23 2 0xF7 0x01
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0x6F 0x21
0x23 2 0xF7 0x00
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x23 2 0x6F 0x1A
0x23 2 0xF7 0x05
0xFF 1 /* delay(ms) */
0xfd 1 1 /* delay(ms) */
0x29 5 0xFF 0xAA 0x55 0x25 0x00
@@ -741,16 +739,16 @@
0x13 1 0x35
0x13 1 0x11
0xFF 120 /* delay(ms) */
0xfd 1 120 /* delay(ms) */
0x13 1 0x29
0xFF 20 /* delay(ms) */
0xFF 0xFF>; /*ending*/
0xfd 1 20 /* delay(ms) */
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_3{
@@ -882,16 +880,16 @@
0x23 2 0xBE 0x50
0x23 2 0x35 0x00
0x13 1 0x11
0xff 200
0xfd 1 200
0x13 1 0x29
0xff 200
0xFF 0xFF>; /*ending*/
0xfd 1 200
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_4{
@@ -1075,7 +1073,7 @@
0x23 2 0xE6 0x02
0x23 2 0xE7 0x0C
0x05 1 0x11
0xff 120 /* delay 120ms */
0xfd 1 120 /* delay 120ms */
0x23 2 0xE0 0x03
0x23 2 0x2B 0x01
@@ -1186,14 +1184,14 @@
0x23 2 0x97 0x00
0x23 2 0xE0 0x00
0x05 1 0x29
0xff 5 /* delay 130ms */
0xFF 0xFF>; /*ending*/
0xfd 1 5 /* delay 130ms */
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_5{
@@ -1421,23 +1419,22 @@
0x23 2 0xE6 0x02 /* Watch dog */
0x23 2 0xE7 0x0C
0x05 1 0x11 /* sleep out */
0xff 120
0xfd 1 120
0x05 1 0x29 /* display on */
0x05 1 0x35
0xFF 20 /* delay(ms) */
0xFF 0xFF>; /*ending*/
0xfd 1 20 /* delay(ms) */
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
};
backlight{
compatible = "amlogic, backlight-g12a";
dev_name = "backlight";
status = "okay";
key_valid = <0>;
pinctrl-names = "pwm_on","pwm_off";
@@ -1495,7 +1492,6 @@
bl_extern{
compatible = "amlogic, bl_extern";
dev_name = "bl_extern";
status = "disabled";
i2c_bus = "i2c_bus_3";

View File

@@ -18,7 +18,6 @@
/ {
lcd{
compatible = "amlogic, lcd-g12b";
dev_name = "lcd";
mode = "tablet";
status = "okay";
key_valid = <0>;
@@ -79,15 +78,15 @@
/* dsi_init: data_type, num, data... */
dsi_init_on = <0x05 1 0x11
0xff 20 /*delay(ms)*/
0xfd 1 20 /*delay(ms)*/
0x05 1 0x29
0xff 20 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 20 /*delay(ms)*/
0xff 0>; /*ending*/
dsi_init_off = <0x05 1 0x28
0xff 10 /*delay(ms)*/
0xfd 1 10 /*delay(ms)*/
0x05 1 0x10
0xff 10 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 10 /*delay(ms)*/
0xff 0>; /*ending*/
extern_init = <0xff>; /*0xff for invalid*/
/* power step: type, index, value, delay(ms) */
@@ -132,15 +131,15 @@
/* dsi_init: data_type, num, data... */
dsi_init_on = <0x05 1 0x11
0xff 200 /*delay(ms)*/
0xfd 1 200 /*delay(ms)*/
0x05 1 0x29
0xff 20 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 20 /*delay(ms)*/
0xff 0>; /*ending*/
dsi_init_off = <0x05 1 0x28
0xff 10 /*delay(ms)*/
0xfd 1 10 /*delay(ms)*/
0x05 1 0x10
0xff 10 /*delay(ms)*/
0xff 0xff>; /*ending*/
0xfd 1 10 /*delay(ms)*/
0xff 0>; /*ending*/
extern_init = <0xff>; /*0xff for invalid*/
/* power step: type, index, value, delay(ms) */
@@ -184,8 +183,8 @@
0>; /*phy_switch(0=auto,1=standard,2=slow)*/
/* dsi_init: data_type, num, data... */
dsi_init_on = <0xff 0xff>; /*ending*/
dsi_init_off = <0xff 0xff>; /*ending*/
dsi_init_on = <0xff 0>; /*ending*/
dsi_init_off = <0xff 0>; /*ending*/
extern_init = <1>; /*0xff for invalid*/
/* power step: type, index, value, delay(ms) */
@@ -234,8 +233,8 @@
0xf0 3 0 0 10 /* reset low, delay 10ms */
0xf0 3 0 1 30 /* reset high, delay 30ms */
0xfc 2 0x04 3 /* check_reg, check_cnt */
0xff 0xff>; /* ending flag */
dsi_init_off = <0xff 0xff>; /* ending flag */
0xff 0>; /* ending flag */
dsi_init_off = <0xff 0>; /* ending flag */
/* extern_init: 0xff for invalid */
extern_init = <2>;
/* power step: type,index,value,delay(ms) */
@@ -254,7 +253,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
i2c_bus = "i2c_bus_0";
key_valid = <0>;
@@ -266,17 +264,17 @@
type = <2>; /* 0=i2c, 1=spi, 2=mipi */
cmd_size = <0xff>;
init_on = <
0xff 10
0xfd 1 10
0x05 1 0x11
0xff 120 /* delay 120ms */
0xfd 1 120 /* delay 120ms */
0x05 1 0x29
0xff 0xff>; /*ending*/
0xff 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_1{
@@ -487,22 +485,22 @@
0x39 4 0xFF 0x98 0x81 0x00
0x15 2 0x3A 0x77
0xff 2
0xfd 1 2
0x15 2 0x36 0x08
0x05 1 0x11 /* display on */
0xff 200
0xfd 1 200
0x05 1 0x29 /* display on */
0xff 200
0xFF 0xFF>; /*ending*/
0xfd 1 200
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
extern_2{
@@ -730,23 +728,22 @@
0x23 2 0xE6 0x02 /* Watch dog */
0x23 2 0xE7 0x0C
0x05 1 0x11 /* sleep out */
0xff 120
0xfd 1 120
0x05 1 0x29 /* display on */
0x05 1 0x35
0xFF 20 /* delay(ms) */
0xFF 0xFF>; /*ending*/
0xfd 1 20 /* delay(ms) */
0xFF 0>; /*ending*/
init_off = <
0x05 1 0x28 /* display off */
0xff 10 /* delay 10ms */
0xfd 1 10 /* delay 10ms */
0x05 1 0x10 /* sleep in */
0xff 150 /* delay 150ms */
0xff 0xff>; /*ending*/
0xfd 1 150 /* delay 150ms */
0xff 0>; /*ending*/
};
};
backlight{
compatible = "amlogic, backlight-g12b";
dev_name = "backlight";
status = "okay";
key_valid = <0>;
pinctrl-names = "pwm_on","pwm_off";
@@ -804,7 +801,6 @@
bl_extern{
compatible = "amlogic, bl_extern";
dev_name = "bl_extern";
status = "disabled";
i2c_bus = "i2c_bus_3";

View File

@@ -18,7 +18,6 @@
/ {
lcd{
compatible = "amlogic, lcd-gxl";
dev_name = "lcd";
mode = "tablet";
status = "okay";
key_valid = <0>;
@@ -96,7 +95,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "disabled";
i2c_bus = "i2c_bus_d";
key_valid = <0>;
@@ -107,30 +105,33 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
i2c_second_address = <0xff>; /* 0xff for none */
i2c_address2 = <0xff>; /* 0xff for none */
cmd_size = <0xff>; /*0xff for dynamic cmd_size*/
/* init on/off:
* fixed cmd_size: (type, value..., delay);
* fixed cmd_size: (type, value...);
* cmd_size include all data.
* dynamic cmd_size: (type, cmd_size, value..., delay);
* cmd_size include value+delay.
* dynamic cmd_size: (type, cmd_size, value...);
* cmd_size include value.
*/
/* type: 0x00=cmd(bit[3:0]=1 for second_addr),
* 0xf0=gpio, 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level,
* fill 0x0 for no use
/* type: 0x00=cmd with delay(bit[3:0]=1 for address2),
* 0xc0=cmd(bit[3:0]=1 for address2),
* 0xf0=gpio,
* 0xfd=delay,
* 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level */
/* delay: unit ms */
init_on = <0x00 8 0x20 0x01 0x02 0x00 0x40 0xFF 0x00 0
0x00 8 0x80 0x02 0x00 0x40 0x62 0x51 0x73 0
0x00 8 0x61 0x06 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00 0
0x00 8 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0x3D 0x02 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0xED 0x0D 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0x23 0x02 0x00 0x00 0x00 0x00 0x00 10
init_on = <
0xc0 7 0x20 0x01 0x02 0x00 0x40 0xFF 0x00
0xc0 7 0x80 0x02 0x00 0x40 0x62 0x51 0x73
0xc0 7 0x61 0x06 0x00 0x00 0x00 0x00 0x00
0xc0 7 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00
0xc0 7 0x13 0x01 0x00 0x00 0x00 0x00 0x00
0xc0 7 0x3D 0x02 0x01 0x00 0x00 0x00 0x00
0xc0 7 0xED 0x0D 0x01 0x00 0x00 0x00 0x00
0xc0 7 0x23 0x02 0x00 0x00 0x00 0x00 0x00
0xfd 1 10 /* delay 10ms */
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
@@ -141,7 +142,6 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1b>; /* 7bit i2c address */
cmd_size = <0xff>; /*0xff for dynamic cmd_size*/
};
};
};/* end of panel */

View File

@@ -18,7 +18,6 @@
/ {
lcd{
compatible = "amlogic, lcd-gxm";
dev_name = "lcd";
mode = "tablet";
status = "okay";
key_valid = <0>;
@@ -96,7 +95,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
i2c_bus = "i2c_bus_d";
key_valid = <0>;
@@ -107,30 +105,33 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
i2c_second_address = <0xff>; /* 0xff for none */
i2c_address2 = <0xff>; /* 0xff for none */
cmd_size = <0xff>; /*0xff for dynamic cmd_size*/
/* init on/off:
* fixed cmd_size: (type, value..., delay);
* fixed cmd_size: (type, value...);
* cmd_size include all data.
* dynamic cmd_size: (type, cmd_size, value..., delay);
* cmd_size include value+delay.
* dynamic cmd_size: (type, cmd_size, value...);
* cmd_size include value.
*/
/* type: 0x00=cmd(bit[3:0]=1 for second_addr),
* 0xf0=gpio, 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level,
* fill 0x0 for no use
/* type: 0x00=cmd with delay(bit[3:0]=1 for address2),
* 0xc0=cmd(bit[3:0]=1 for address2),
* 0xf0=gpio,
* 0xfd=delay,
* 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level */
/* delay: unit ms */
init_on = <0x00 8 0x20 0x01 0x02 0x00 0x40 0xFF 0x00 0
0x00 8 0x80 0x02 0x00 0x40 0x62 0x51 0x73 0
0x00 8 0x61 0x06 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00 0
0x00 8 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0x3D 0x02 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0xED 0x0D 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0x23 0x02 0x00 0x00 0x00 0x00 0x00 10
init_on = <
0xc0 7 0x20 0x01 0x02 0x00 0x40 0xFF 0x00
0xc0 7 0x80 0x02 0x00 0x40 0x62 0x51 0x73
0xc0 7 0x61 0x06 0x00 0x00 0x00 0x00 0x00
0xc0 7 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00
0xc0 7 0x13 0x01 0x00 0x00 0x00 0x00 0x00
0xc0 7 0x3D 0x02 0x01 0x00 0x00 0x00 0x00
0xc0 7 0xED 0x0D 0x01 0x00 0x00 0x00 0x00
0xc0 7 0x23 0x02 0x00 0x00 0x00 0x00 0x00
0xfd 1 10 /* delay 10ms */
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
@@ -141,7 +142,6 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1b>; /* 7bit i2c address */
cmd_size = <0xff>; /*0xff for dynamic cmd_size*/
};
};
};/* end of panel */

View File

@@ -18,7 +18,6 @@
/ {
lcd {
compatible = "amlogic, lcd-txl";
dev_name = "lcd";
mode = "tv";
status = "okay";
fr_auto_policy = <1>; /* 0=disable, 1=60/50hz, 2=60/50/48hz */
@@ -416,7 +415,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
key_valid = <1>;
i2c_bus = "i2c_bus_c";
@@ -436,31 +434,33 @@
status = "disabled";
type = <0>; /*0=i2c, 1=spi, 2=mipi*/
i2c_address = <0x1c>; /*7bit i2c_addr*/
i2c_second_address = <0xff>;
i2c_address2 = <0xff>;
cmd_size = <0xff>; /*dynamic cmd_size*/
/* init on/off:
* fixed cmd_size: (type, value..., delay);
* fixed cmd_size: (type, value...);
* cmd_size include all data.
* dynamic cmd_size: (type, cmd_size, value..., delay);
* cmd_size include value+delay.
* dynamic cmd_size: (type, cmd_size, value...);
* cmd_size include value.
*/
/* type: 0x00=cmd(bit[3:0]=1 for second_addr),
* 0xf0=gpio, 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level,
* fill 0x0 for no use
/* type: 0x00=cmd with delay(bit[3:0]=1 for address2),
* 0xc0=cmd(bit[3:0]=1 for address2),
* 0xf0=gpio,
* 0xfd=delay,
* 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level */
/* delay: unit ms */
init_on = <
0x00 8 0x20 0x01 0x02 0x00 0x40 0xFF 0x00 0
0x00 8 0x80 0x02 0x00 0x40 0x62 0x51 0x73 0
0x00 8 0x61 0x06 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00 0
0x00 8 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0x3D 0x02 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0xED 0x0D 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0x23 0x02 0x00 0x00 0x00 0x00 0x00 10
0xc0 7 0x20 0x01 0x02 0x00 0x40 0xFF 0x00
0xc0 7 0x80 0x02 0x00 0x40 0x62 0x51 0x73
0xc0 7 0x61 0x06 0x00 0x00 0x00 0x00 0x00
0xc0 7 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00
0xc0 7 0x13 0x01 0x00 0x00 0x00 0x00 0x00
0xc0 7 0x3D 0x02 0x01 0x00 0x00 0x00 0x00
0xc0 7 0xED 0x0D 0x01 0x00 0x00 0x00 0x00
0xc0 7 0x23 0x02 0x00 0x00 0x00 0x00 0x00
0xfd 1 10 /* delay 10ms */
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
@@ -470,13 +470,11 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
cmd_size = <9>;
};
};
backlight{
compatible = "amlogic, backlight-txl";
dev_name = "backlight";
status = "okay";
key_valid = <1>;
pinctrl-names = "pwm_on","pwm_vs_on",

View File

@@ -18,7 +18,6 @@
/ {
lcd {
compatible = "amlogic, lcd-txlx";
dev_name = "lcd";
mode = "tv";
status = "okay";
fr_auto_policy = <1>; /* 0=disable, 1=60/50hz, 2=60/50/48hz */
@@ -454,7 +453,6 @@
lcd_extern{
compatible = "amlogic, lcd_extern";
dev_name = "lcd_extern";
status = "okay";
key_valid = <1>;
i2c_bus = "i2c_bus_c";
@@ -474,31 +472,33 @@
status = "disabled";
type = <0>; /*0=i2c, 1=spi, 2=mipi*/
i2c_address = <0x1c>; /*7bit i2c_addr*/
i2c_second_address = <0xff>;
i2c_address2 = <0xff>;
cmd_size = <0xff>; /*dynamic cmd_size*/
/* init on/off:
* fixed cmd_size: (type, value..., delay);
* fixed cmd_size: (type, value...);
* cmd_size include all data.
* dynamic cmd_size: (type, cmd_size, value..., delay);
* cmd_size include value+delay.
* dynamic cmd_size: (type, cmd_size, value...);
* cmd_size include value.
*/
/* type: 0x00=cmd(bit[3:0]=1 for second_addr),
* 0xf0=gpio, 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level,
* fill 0x0 for no use
/* type: 0x00=cmd with delay(bit[3:0]=1 for address2),
* 0xc0=cmd(bit[3:0]=1 for address2),
* 0xf0=gpio,
* 0xfd=delay,
* 0xff=ending
*/
/* value: i2c or spi cmd, or gpio index & level */
/* delay: unit ms */
init_on = <
0x00 8 0x20 0x01 0x02 0x00 0x40 0xFF 0x00 0
0x00 8 0x80 0x02 0x00 0x40 0x62 0x51 0x73 0
0x00 8 0x61 0x06 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00 0
0x00 8 0x13 0x01 0x00 0x00 0x00 0x00 0x00 0
0x00 8 0x3D 0x02 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0xED 0x0D 0x01 0x00 0x00 0x00 0x00 0
0x00 8 0x23 0x02 0x00 0x00 0x00 0x00 0x00 10
0xc0 7 0x20 0x01 0x02 0x00 0x40 0xFF 0x00
0xc0 7 0x80 0x02 0x00 0x40 0x62 0x51 0x73
0xc0 7 0x61 0x06 0x00 0x00 0x00 0x00 0x00
0xc0 7 0xC1 0x05 0x0F 0x00 0x08 0x70 0x00
0xc0 7 0x13 0x01 0x00 0x00 0x00 0x00 0x00
0xc0 7 0x3D 0x02 0x01 0x00 0x00 0x00 0x00
0xc0 7 0xED 0x0D 0x01 0x00 0x00 0x00 0x00
0xc0 7 0x23 0x02 0x00 0x00 0x00 0x00 0x00
0xfd 1 10 /* delay 10ms */
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
@@ -508,13 +508,60 @@
status = "disabled";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x1c>; /* 7bit i2c address */
cmd_size = <9>;
};
extern_2{
index = <2>;
extern_name = "i2c_ANX6862_7911";
status = "okay";
type = <0>; /* 0=i2c, 1=spi, 2=mipi */
i2c_address = <0x20>; /* 7bit i2c address */
i2c_address2 = <0x74>; /* 7bit i2c address */
cmd_size = <0xff>;
init_on = <
0xc0 2 0x01 0x2b
0xc0 2 0x02 0x05
0xc0 2 0x03 0x00
0xc0 2 0x04 0x00
0xc0 2 0x05 0x0c
0xc0 2 0x06 0x04
0xc0 2 0x07 0x21
0xc0 2 0x08 0x0f
0xc0 2 0x09 0x04
0xc0 2 0x0a 0x00
0xc0 2 0x0b 0x04
0xc0 2 0xff 0x00
0xfd 1 100 /* delay 100ms */
0xc1 2 0x01 0xca
0xc1 2 0x02 0x3b
0xc1 2 0x03 0x33
0xc1 2 0x04 0x05
0xc1 2 0x05 0x2c
0xc1 2 0x06 0xf2
0xc1 2 0x07 0x9c
0xc1 2 0x08 0x1b
0xc1 2 0x09 0x82
0xc1 2 0x0a 0x3d
0xc1 2 0x0b 0x20
0xc1 2 0x0c 0x11
0xc1 2 0x0d 0xc4
0xc1 2 0x0e 0x1a
0xc1 2 0x0f 0x31
0xc1 2 0x10 0x4c
0xc1 2 0x11 0x12
0xc1 2 0x12 0x90
0xc1 2 0x13 0xf7
0xc1 2 0x14 0x0c
0xc1 2 0x15 0x20
0xc1 2 0x16 0x13
0xff 0>; /*ending*/
init_off = <0xff 0>; /*ending*/
};
};
backlight{
compatible = "amlogic, backlight-txlx";
dev_name = "backlight";
status = "okay";
key_valid = <1>;
pinctrl-names = "pwm_on","pwm_vs_on",
@@ -678,7 +725,6 @@
local_dimming_device {
compatible = "amlogic, ldim_dev";
dev_name = "ldim_dev";
status = "okay";
pinctrl-names = "ldim_pwm",
"ldim_pwm_vs",
@@ -745,30 +791,32 @@
dim_max_min = <0xfff 0x7f>; /* dim_max, dim_min */
ldim_region_mapping = <0 1 2 3 4 5 6 7 8 9>;
cmd_size = <4>;
/* init: (type, data..., delay),
* must match cmd_size for every group
cmd_size = <0xff>;
/* init: (type, data...) */
/* type: 0x00=cmd with delay,
* 0xc0=cmd,
* 0xfd=delay,
* 0xff=ending
*/
/* type: 0x00=cmd, 0xff=ending*/
/* data: spi data, fill 0x0 for no use */
/* delay: unit ms */
init_on = <
0x00 0x23 0x03 0x00
0x00 0x24 0xff 0x00
0x00 0x25 0x00 0x00
0x00 0x26 0x00 0x00
0x00 0x27 0x60 0x00
0x00 0x29 0x00 0x00
0x00 0x2a 0x00 0x00
0x00 0x2b 0x00 0x00
0x00 0x2c 0x73 0x00
0x00 0x2d 0x37 0x00
0x00 0x31 0x93 0x00
0x00 0x32 0x0f 0x00
0x00 0x33 0xff 0x00
0x00 0x34 0xc8 0x00
0x00 0x35 0xbf 0x00
0xff 0x00 0x00 0x00>;
0xc0 2 0x23 0x03
0xc0 2 0x24 0xff
0xc0 2 0x25 0x00
0xc0 2 0x26 0x00
0xc0 2 0x27 0x60
0xc0 2 0x29 0x00
0xc0 2 0x2a 0x00
0xc0 2 0x2b 0x00
0xc0 2 0x2c 0x73
0xc0 2 0x2d 0x37
0xc0 2 0x31 0x93
0xc0 2 0x32 0x0f
0xc0 2 0x33 0xff
0xc0 2 0x34 0xc8
0xc0 2 0x35 0xbf
0xff 0>;
};
};

View File

@@ -1480,6 +1480,20 @@
reg = <0x1c>;
status = "okay";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX6862";
reg = <0x20>;
status = "okay";
};
lcd_extern_i2c2: lcd_extern_i2c@2 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX7911";
reg = <0x74>;
status = "okay";
};
};
&i2c1 {

View File

@@ -1485,6 +1485,20 @@
reg = <0x1c>;
status = "okay";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX6862";
reg = <0x20>;
status = "okay";
};
lcd_extern_i2c2: lcd_extern_i2c@2 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX7911";
reg = <0x74>;
status = "okay";
};
};
&i2c1 {

View File

@@ -1478,6 +1478,20 @@
reg = <0x1c>;
status = "okay";
};
lcd_extern_i2c1: lcd_extern_i2c@1 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX6862";
reg = <0x20>;
status = "okay";
};
lcd_extern_i2c2: lcd_extern_i2c@2 {
compatible = "lcd_ext, i2c";
dev_name = "i2c_ANX7911";
reg = <0x74>;
status = "okay";
};
};
&i2c1 {

View File

@@ -284,6 +284,7 @@ CONFIG_AMLOGIC_LCD=y
CONFIG_AMLOGIC_LCD_TV=y
CONFIG_AMLOGIC_LCD_TABLET=y
CONFIG_AMLOGIC_LCD_EXTERN=y
CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6862_7911=y
CONFIG_AMLOGIC_BACKLIGHT=y
CONFIG_AMLOGIC_BL_EXTERN=y
CONFIG_AMLOGIC_BL_EXTERN_I2C_LP8556=y

View File

@@ -25,20 +25,16 @@
#include <linux/spinlock.h>
#include <linux/irq.h>
#include <linux/notifier.h>
#include <linux/reboot.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/amlogic/aml_gpio_consumer.h>
#include <linux/amlogic/media/vout/lcd/aml_ldim.h>
#include <linux/amlogic/media/vout/lcd/aml_bl.h>
#include "ldim_drv.h"
#include "ldim_dev_drv.h"
#define INT_VIU_VSYNC 35
#define NORMAL_MSG (0<<7)
#define BROADCAST_MSG (1<<7)
#define BLOCK_DATA (0<<6)
@@ -64,6 +60,7 @@ struct iw7027_s {
int cs_clk_delay;
unsigned char cmd_size;
unsigned char *init_data;
unsigned int init_data_cnt;
struct class cls;
};
struct iw7027_s *bl_iw7027;
@@ -151,9 +148,114 @@ static int iw7027_wregs(struct spi_device *spi, u8 addr, u8 *val, int len)
return ret;
}
static int ldim_power_cmd_dynamic_size(void)
{
unsigned char *table;
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int delay_ms, ret = 0;
table = bl_iw7027->init_data;
max_len = bl_iw7027->init_data_cnt;
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (ldim_debug_print) {
LDIMPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, table[i+1]);
}
cmd_size = table[i+1];
if (cmd_size == 0)
goto power_cmd_dynamic_next;
if ((i + 2 + cmd_size) > max_len)
break;
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += table[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = iw7027_wreg(bl_iw7027->spi,
table[i+2], table[i+3]);
udelay(1);
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = iw7027_wreg(bl_iw7027->spi,
table[i+2], table[i+3]);
udelay(1);
if (table[i+4] > 0)
mdelay(table[i+4]);
} else {
LDIMERR("%s: type 0x%02x invalid\n", __func__, type);
}
power_cmd_dynamic_next:
i += (cmd_size + 2);
step++;
}
return ret;
}
static int ldim_power_cmd_fixed_size(void)
{
unsigned char *table;
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int delay_ms, ret = 0;
cmd_size = bl_iw7027->cmd_size;
if (cmd_size < 2) {
LDIMERR("%s: invalid cmd_size %d\n", __func__, cmd_size);
return -1;
}
table = bl_iw7027->init_data;
max_len = bl_iw7027->init_data_cnt;
while ((i + cmd_size) <= max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (ldim_debug_print) {
LDIMPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, cmd_size);
}
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < (cmd_size - 1); j++)
delay_ms += table[i+1+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = iw7027_wreg(bl_iw7027->spi,
table[i+1], table[i+2]);
udelay(1);
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = iw7027_wreg(bl_iw7027->spi,
table[i+1], table[i+2]);
udelay(1);
if (table[i+3] > 0)
mdelay(table[i+3]);
} else {
LDIMERR("%s: type 0x%02x invalid\n", __func__, type);
}
i += cmd_size;
step++;
}
return ret;
}
static int iw7027_power_on_init(int flag)
{
unsigned char addr, val;
unsigned char cmd_size;
int i, ret = 0;
LDIMPR("%s: spi_op_flag=%d\n", __func__, iw7027_spi_op_flag);
@@ -173,20 +275,15 @@ static int iw7027_power_on_init(int flag)
iw7027_spi_op_flag = 1;
iw7027_power_reset_p:
for (i = 0; i < LDIM_SPI_INIT_ON_SIZE; i += bl_iw7027->cmd_size) {
if (bl_iw7027->init_data[i] == 0xff) {
if (bl_iw7027->init_data[i+3] > 0)
mdelay(bl_iw7027->init_data[i+3]);
break;
} else if (bl_iw7027->init_data[i] == 0x0) {
addr = bl_iw7027->init_data[i+1];
val = bl_iw7027->init_data[i+2];
ret = iw7027_wreg(bl_iw7027->spi, addr, val);
udelay(1);
}
if (bl_iw7027->init_data[i+3] > 0)
mdelay(bl_iw7027->init_data[i+3]);
cmd_size = bl_iw7027->cmd_size;
if (cmd_size < 1) {
LDIMERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
return -1;
}
if (cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC)
ret = ldim_power_cmd_dynamic_size();
else
ret = ldim_power_cmd_fixed_size();
if (flag == IW7027_POWER_RESET)
return ret;
@@ -672,6 +769,7 @@ int ldim_dev_iw7027_probe(void)
bl_iw7027->cs_clk_delay = ldim_drv->ldev_conf->cs_clk_delay;
bl_iw7027->cmd_size = ldim_drv->ldev_conf->cmd_size;
bl_iw7027->init_data = ldim_drv->ldev_conf->init_on;
bl_iw7027->init_data_cnt = ldim_drv->ldev_conf->init_on_cnt;
val_brightness = kcalloc(ldim_drv->ldev_conf->bl_regnum * 2,
sizeof(unsigned char), GFP_KERNEL);

View File

@@ -55,24 +55,27 @@ static struct spi_board_info ldim_spi_dev = {
.controller_data = NULL,
};
static unsigned char ldim_ini_data_on[LDIM_SPI_INIT_ON_SIZE];
static unsigned char ldim_ini_data_off[LDIM_SPI_INIT_OFF_SIZE];
static unsigned char *table_init_on_dft;
static unsigned char *table_init_off_dft;
struct ldim_dev_config_s ldim_dev_config = {
.type = LDIM_DEV_TYPE_NORMAL,
.cs_hold_delay = 0,
.cs_clk_delay = 0,
.en_gpio = 0xff,
.en_gpio = LCD_EXT_GPIO_INVALID,
.en_gpio_on = 1,
.en_gpio_off = 0,
.lamp_err_gpio = 0xff,
.lamp_err_gpio = LCD_EXT_GPIO_INVALID,
.fault_check = 0,
.write_check = 0,
.dim_min = 0x7f, /* min 3% duty */
.dim_max = 0xfff,
.init_loaded = 0,
.cmd_size = 4,
.init_on = ldim_ini_data_on,
.init_off = ldim_ini_data_off,
.init_on = NULL,
.init_off = NULL,
.init_on_cnt = 0,
.init_off_cnt = 0,
.pwm_config = {
.pwm_method = BL_PWM_POSITIVE,
.pwm_port = BL_PWM_MAX,
@@ -83,39 +86,6 @@ struct ldim_dev_config_s ldim_dev_config = {
.bl_regnum = 0,
};
#if 0
static void ldim_gpio_release(int index)
{
struct bl_gpio_s *ld_gpio;
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
if (index >= BL_GPIO_NUM_MAX) {
LDIMERR("gpio index %d, exit\n", index);
return;
}
ld_gpio = &ldim_gpio[index];
if (ld_gpio->flag == 0) {
if (ldim_debug_print) {
LDIMPR("gpio %s[%d] is not registered\n",
ld_gpio->name, index);
}
return;
}
if (IS_ERR(ld_gpio->gpio)) {
LDIMERR("gpio %s[%d]: %p, err: %ld\n",
ld_gpio->name, index, ld_gpio->gpio,
PTR_ERR(ld_gpio->gpio));
return;
}
/* release gpio */
devm_gpiod_put(ldim_drv->dev, ld_gpio->gpio);
ld_gpio->flag = 0;
if (ldim_debug_print)
LDIMPR("release gpio %s[%d]\n", ld_gpio->name, index);
}
#endif
static void ldim_gpio_probe(int index)
{
struct bl_gpio_s *ld_gpio;
@@ -360,7 +330,129 @@ static int ldim_pwm_vs_update(void)
return ret;
}
static void ldim_config_print(void)
#define EXT_LEN_MAX 500
static void ldim_dev_init_table_dynamic_size_print(
struct ldim_dev_config_s *econf, int flag)
{
int i, j, k, max_len;
unsigned char cmd_size;
char *str;
unsigned char *table;
str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL);
if (str == NULL) {
LDIMERR("%s: str malloc error\n", __func__);
return;
}
if (flag) {
pr_info("power on:\n");
table = econf->init_on;
max_len = econf->init_off_cnt;
} else {
pr_info("power off:\n");
table = econf->init_off;
max_len = econf->init_off_cnt;
}
if (table == NULL) {
LDIMERR("init_table %d is NULL\n", flag);
kfree(str);
return;
}
i = 0;
while ((i + 1) < max_len) {
if (table[i] == LCD_EXT_CMD_TYPE_END) {
pr_info(" 0x%02x,%d,\n", table[i], table[i+1]);
break;
}
cmd_size = table[i+1];
k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,",
table[i], cmd_size);
if (cmd_size == 0)
goto init_table_dynamic_print_next;
if (i + 2 + cmd_size > max_len) {
pr_info("cmd_size out of support\n");
break;
}
if (table[i] == LCD_EXT_CMD_TYPE_DELAY) {
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"%d,", table[i+2+j]);
}
} else if (table[i] == LCD_EXT_CMD_TYPE_CMD) {
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"0x%02x,", table[i+2+j]);
}
} else if (table[i] == LCD_EXT_CMD_TYPE_CMD_DELAY) {
for (j = 0; j < (cmd_size - 1); j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"0x%02x,", table[i+2+j]);
}
snprintf(str+k, EXT_LEN_MAX,
"%d,", table[i+cmd_size+1]);
} else {
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"0x%02x,", table[i+2+j]);
}
}
init_table_dynamic_print_next:
pr_info("%s\n", str);
i += (cmd_size + 2);
}
kfree(str);
}
static void ldim_dev_init_table_fixed_size_print(
struct ldim_dev_config_s *econf, int flag)
{
int i, j, k, max_len;
unsigned char cmd_size;
char *str;
unsigned char *table;
str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL);
if (str == NULL) {
LDIMERR("%s: str malloc error\n", __func__);
return;
}
cmd_size = econf->cmd_size;
if (flag) {
pr_info("power on:\n");
table = econf->init_on;
max_len = econf->init_on_cnt;
} else {
pr_info("power off:\n");
table = econf->init_off;
max_len = econf->init_off_cnt;
}
if (table == NULL) {
LDIMERR("init_table %d is NULL\n", flag);
kfree(str);
return;
}
i = 0;
while ((i + cmd_size) <= max_len) {
k = snprintf(str, EXT_LEN_MAX, " ");
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX, " 0x%02x",
table[i+j]);
}
pr_info("%s\n", str);
if (table[i] == LCD_EXT_CMD_TYPE_END)
break;
i += cmd_size;
}
kfree(str);
}
static void ldim_dev_config_print(void)
{
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
struct aml_bl_drv_s *bl_drv = aml_bl_get_driver();
@@ -420,8 +512,7 @@ static void ldim_config_print(void)
"cs_clk_delay = %d\n"
"lamp_err_gpio = %d\n"
"fault_check = %d\n"
"write_check = %d\n"
"cmd_size = %d\n\n",
"write_check = %d\n\n",
ldim_drv->spi_dev->modalias,
ldim_drv->spi_dev->mode,
ldim_drv->spi_dev->max_speed_hz,
@@ -431,8 +522,7 @@ static void ldim_config_print(void)
ldim_drv->ldev_conf->cs_clk_delay,
ldim_drv->ldev_conf->lamp_err_gpio,
ldim_drv->ldev_conf->fault_check,
ldim_drv->ldev_conf->write_check,
ldim_drv->ldev_conf->cmd_size);
ldim_drv->ldev_conf->write_check);
break;
case LDIM_DEV_TYPE_I2C:
break;
@@ -492,9 +582,32 @@ static void ldim_config_print(void)
}
}
pr_info("pinmux_flag: %d\n"
"pinmux_pointer: 0x%p\n",
"pinmux_pointer: 0x%p\n\n",
ldim_drv->pinmux_flag,
ldim_drv->pin);
if (ldim_drv->ldev_conf->cmd_size > 0) {
pr_info("table_loaded: %d\n"
"cmd_size: %d\n"
"init_on_cnt: %d\n"
"init_off_cnt: %d\n",
ldim_drv->ldev_conf->init_loaded,
ldim_drv->ldev_conf->cmd_size,
ldim_drv->ldev_conf->init_on_cnt,
ldim_drv->ldev_conf->init_off_cnt);
if (ldim_drv->ldev_conf->cmd_size ==
LCD_EXT_CMD_SIZE_DYNAMIC) {
ldim_dev_init_table_dynamic_size_print(
ldim_drv->ldev_conf, 1);
ldim_dev_init_table_dynamic_size_print(
ldim_drv->ldev_conf, 0);
} else {
ldim_dev_init_table_fixed_size_print(
ldim_drv->ldev_conf, 1);
ldim_dev_init_table_fixed_size_print(
ldim_drv->ldev_conf, 0);
}
}
} else {
pr_info("device config is null\n");
}
@@ -564,13 +677,206 @@ static int ldim_dev_pwm_channel_register(struct bl_pwm_config_s *bl_pwm,
}
static int ldim_dev_init_table_dynamic_size_load_dts(
struct device_node *of_node,
struct ldim_dev_config_s *ldconf, int flag)
{
unsigned char cmd_size, type;
int i = 0, j, val, max_len, step = 0, ret = 0;
unsigned char *table;
char propname[20];
if (flag) {
table = table_init_on_dft;
max_len = LDIM_INIT_ON_MAX;
sprintf(propname, "init_on");
} else {
table = table_init_off_dft;
max_len = LDIM_INIT_OFF_MAX;
sprintf(propname, "init_off");
}
if (table == NULL) {
LDIMERR("%s: init_table is null\n", __func__);
return -1;
}
while ((i + 1) < max_len) {
/* type */
ret = of_property_read_u32_index(of_node, propname, i, &val);
if (ret) {
LDIMERR("%s: get %s type failed, step %d\n",
ldconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
table[i] = (unsigned char)val;
type = table[i];
/* cmd_size */
ret = of_property_read_u32_index(of_node, propname,
(i+1), &val);
if (ret) {
LDIMERR("%s: get %s cmd_size failed, step %d\n",
ldconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
table[i+1] = (unsigned char)val;
cmd_size = table[i+1];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (cmd_size == 0)
goto init_table_dynamic_dts_next;
if ((i + 2 + cmd_size) > max_len) {
LDIMERR("%s: %s cmd_size out of support, step %d\n",
ldconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
/* data */
for (j = 0; j < cmd_size; j++) {
ret = of_property_read_u32_index(
of_node, propname, (i+2+j), &val);
if (ret) {
LDIMERR("%s: get %s data failed, step %d\n",
ldconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
table[i+2+j] = (unsigned char)val;
}
init_table_dynamic_dts_next:
i += (cmd_size + 2);
step++;
}
if (flag)
ldconf->init_on_cnt = i + 2;
else
ldconf->init_off_cnt = i + 2;
return 0;
}
static int ldim_dev_init_table_fixed_size_load_dts(
struct device_node *of_node,
struct ldim_dev_config_s *ldconf, int flag)
{
unsigned char cmd_size;
int i = 0, j, val, max_len, step = 0, ret = 0;
unsigned char *table;
char propname[20];
cmd_size = ldconf->cmd_size;
if (flag) {
table = table_init_on_dft;
max_len = LDIM_INIT_ON_MAX;
sprintf(propname, "init_on");
} else {
table = table_init_off_dft;
max_len = LDIM_INIT_OFF_MAX;
sprintf(propname, "init_off");
}
if (table == NULL) {
LDIMERR("%s: init_table is null\n", __func__);
return -1;
}
while (i < max_len) { /* group detect */
if ((i + cmd_size) > max_len) {
LDIMERR("%s: %s cmd_size out of support, step %d\n",
ldconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
return -1;
}
for (j = 0; j < cmd_size; j++) {
ret = of_property_read_u32_index(
of_node, propname, (i+j), &val);
if (ret) {
LDIMERR("%s: get %s failed, step %d\n",
ldconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
return -1;
}
table[i+j] = (unsigned char)val;
}
if (table[i] == LCD_EXT_CMD_TYPE_END)
break;
i += cmd_size;
step++;
}
if (flag)
ldconf->init_on_cnt = i + cmd_size;
else
ldconf->init_off_cnt = i + cmd_size;
return 0;
}
static int ldim_dev_tablet_init_dft_malloc(void)
{
table_init_on_dft = kcalloc(LDIM_INIT_ON_MAX,
sizeof(unsigned char), GFP_KERNEL);
if (table_init_on_dft == NULL) {
LDIMERR("failed to alloc init_on table\n");
return -1;
}
table_init_off_dft = kcalloc(LDIM_INIT_OFF_MAX,
sizeof(unsigned char), GFP_KERNEL);
if (table_init_off_dft == NULL) {
LDIMERR("failed to alloc init_off table\n");
kfree(table_init_on_dft);
return -1;
}
table_init_on_dft[0] = LCD_EXT_CMD_TYPE_END;
table_init_on_dft[1] = 0;
table_init_off_dft[0] = LCD_EXT_CMD_TYPE_END;
table_init_off_dft[1] = 0;
return 0;
}
static int ldim_dev_table_init_save(struct ldim_dev_config_s *ldconf)
{
if (ldconf->init_on_cnt > 0) {
ldconf->init_on = kcalloc(ldconf->init_on_cnt,
sizeof(unsigned char), GFP_KERNEL);
if (ldconf->init_on == NULL) {
LDIMERR("failed to alloc init_on table\n");
return -1;
}
memcpy(ldconf->init_on, table_init_on_dft,
ldconf->init_on_cnt*sizeof(unsigned char));
}
if (ldconf->init_off_cnt > 0) {
ldconf->init_off = kcalloc(ldconf->init_off_cnt,
sizeof(unsigned char), GFP_KERNEL);
if (ldconf->init_off == NULL) {
LDIMERR("failed to alloc init_off table\n");
kfree(ldconf->init_on);
return -1;
}
memcpy(ldconf->init_off, table_init_off_dft,
ldconf->init_on_cnt*sizeof(unsigned char));
}
return 0;
}
static int ldim_dev_get_config_from_dts(struct device_node *np, int index)
{
char ld_propname[20];
struct device_node *child;
const char *str;
unsigned int *temp, val;
int i, j;
int i;
int ret = 0;
struct aml_ldim_driver_s *ldim_drv = aml_ldim_get_driver();
@@ -580,11 +886,6 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index)
return -1;
}
memset(ldim_dev_config.init_on, 0, LDIM_SPI_INIT_ON_SIZE);
memset(ldim_dev_config.init_off, 0, LDIM_SPI_INIT_OFF_SIZE);
ldim_dev_config.init_on[0] = 0xff;
ldim_dev_config.init_off[0] = 0xff;
/* get device config */
sprintf(ld_propname, "ldim_dev_%d", index);
LDIMPR("load: %s\n", ld_propname);
@@ -701,6 +1002,9 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index)
goto ldim_get_config_err;
}
ret = ldim_dev_tablet_init_dft_malloc();
if (ret)
goto ldim_get_config_err;
switch (ldim_dev_config.type) {
case LDIM_DEV_TYPE_SPI:
/* get spi config */
@@ -760,11 +1064,12 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index)
ret = of_property_read_u32(child, "lamp_err_gpio", &val);
if (ret) {
ldim_dev_config.lamp_err_gpio = BL_GPIO_NUM_MAX;
ldim_dev_config.lamp_err_gpio = LCD_EXT_GPIO_INVALID;
ldim_dev_config.fault_check = 0;
} else {
if (val >= BL_GPIO_NUM_MAX) {
ldim_dev_config.lamp_err_gpio = BL_GPIO_NUM_MAX;
ldim_dev_config.lamp_err_gpio =
LCD_EXT_GPIO_INVALID;
ldim_dev_config.fault_check = 0;
} else {
ldim_dev_config.lamp_err_gpio = val;
@@ -786,70 +1091,35 @@ static int ldim_dev_get_config_from_dts(struct device_node *np, int index)
ret = of_property_read_u32(child, "cmd_size", &val);
if (ret) {
LDIMPR("no cmd_size\n");
ldim_dev_config.cmd_size = 1;
ldim_dev_config.cmd_size = 0;
} else {
if (val > 1)
ldim_dev_config.cmd_size = (unsigned char)val;
else
ldim_dev_config.cmd_size = 1;
}
ret = of_property_read_u32_index(child, "init_on", 0, &val);
if (ret) {
LDIMPR("no init_on\n");
ldim_dev_config.init_on[0] = 0xff;
goto ldim_get_init_off;
ldim_dev_config.cmd_size = (unsigned char)val;
}
if (ldim_dev_config.cmd_size > 1) {
i = 0;
while (i < LDIM_SPI_INIT_ON_SIZE) {
for (j = 0; j < ldim_dev_config.cmd_size; j++) {
ret = of_property_read_u32_index(child,
"init_on", (i + j), &val);
if (ret) {
LDIMERR("failed init_on\n");
ldim_dev_config.init_on[i]
= 0xff;
goto ldim_get_init_off;
}
ldim_dev_config.init_on[i + j] =
(unsigned char)val;
}
if (ldim_dev_config.init_on[i] == 0xff)
break;
i += ldim_dev_config.cmd_size;
}
}
ldim_get_init_off:
ret = of_property_read_u32_index(child, "init_off", 0, &val);
if (ret) {
LDIMPR("no init_off\n");
ldim_dev_config.init_off[0] = 0xff;
goto ldim_get_config_end;
if (ldim_debug_print) {
LDIMPR("%s: cmd_size = %d\n",
ldim_dev_config.name,
ldim_dev_config.cmd_size);
}
if (ldim_dev_config.cmd_size > 1) {
i = 0;
while (i < LDIM_SPI_INIT_OFF_SIZE) {
for (j = 0; j < ldim_dev_config.cmd_size; j++) {
ret = of_property_read_u32_index(child,
"init_off", (i + j), &val);
if (ret) {
LDIMERR("failed init_on\n");
ldim_dev_config.init_off[i]
= 0xff;
goto ldim_get_config_end;
}
ldim_dev_config.init_off[i + j] =
(unsigned char)val;
}
if (ldim_dev_config.init_off[i] == 0xff)
break;
if (ldim_dev_config.cmd_size == 0)
break;
i += ldim_dev_config.cmd_size;
}
if (ldim_dev_config.cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) {
ret = ldim_dev_init_table_dynamic_size_load_dts(
child, &ldim_dev_config, 1);
if (ret)
break;
ret = ldim_dev_init_table_dynamic_size_load_dts(
child, &ldim_dev_config, 0);
} else {
ret = ldim_dev_init_table_fixed_size_load_dts(
child, &ldim_dev_config, 1);
if (ret)
break;
ret = ldim_dev_init_table_fixed_size_load_dts(
child, &ldim_dev_config, 0);
}
ldim_get_config_end:
if (ret == 0)
ldim_dev_config.init_loaded = 1;
break;
case LDIM_DEV_TYPE_I2C:
break;
@@ -858,9 +1128,20 @@ ldim_get_config_end:
break;
}
if (ldim_dev_config.init_loaded > 0) {
ret = ldim_dev_table_init_save(&ldim_dev_config);
if (ret)
goto ldim_get_config_init_table_err;
}
kfree(table_init_on_dft);
kfree(table_init_off_dft);
kfree(temp);
return 0;
ldim_get_config_init_table_err:
kfree(table_init_on_dft);
kfree(table_init_off_dft);
ldim_get_config_err:
kfree(temp);
return -1;
@@ -936,7 +1217,7 @@ static int ldim_dev_probe(struct platform_device *pdev)
ldim_drv->ldev_conf = &ldim_dev_config;
ldim_drv->pinmux_ctrl = ldim_pwm_pinmux_ctrl;
ldim_drv->pwm_vs_update = ldim_pwm_vs_update;
ldim_drv->config_print = ldim_config_print,
ldim_drv->config_print = ldim_dev_config_print,
ldim_dev_get_config_from_dts(pdev->dev.of_node,
ldim_drv->dev_index);

View File

@@ -31,6 +31,9 @@
static struct aml_bl_extern_driver_s bl_extern_driver;
static unsigned char *table_init_on_dft;
static unsigned char *table_init_off_dft;
static int bl_extern_set_level(unsigned int level)
{
struct aml_bl_drv_s *bl_drv = aml_bl_get_driver();
@@ -40,6 +43,11 @@ static int bl_extern_set_level(unsigned int level)
if (bl_drv == NULL)
return -1;
bl_extern_driver.brightness = level;
if (bl_extern_driver.status == 0)
return 0;
level_max = bl_drv->bconf->level_max;
level_min = bl_drv->bconf->level_min;
dim_max = bl_extern_driver.config.dim_max;
@@ -47,10 +55,6 @@ static int bl_extern_set_level(unsigned int level)
level = dim_min - ((level - level_min) * (dim_min - dim_max)) /
(level_max - level_min);
bl_extern_driver.brightness = level;
if (bl_extern_driver.status == 0)
return 0;
if (bl_extern_driver.device_bri_update)
ret = bl_extern_driver.device_bri_update(level);
@@ -72,6 +76,7 @@ static int bl_extern_power_on(void)
return ret;
}
static int bl_extern_power_off(void)
{
int ret = 0;
@@ -100,9 +105,16 @@ static struct aml_bl_extern_driver_s bl_extern_driver = {
.name = "none",
.type = BL_EXTERN_MAX,
.i2c_addr = 0xff,
.i2c_bus = BL_EXTERN_I2C_BUS_MAX,
.i2c_bus = LCD_EXT_I2C_BUS_MAX,
.dim_min = 10,
.dim_max = 255,
.init_loaded = 0,
.cmd_size = 0,
.init_on = NULL,
.init_off = NULL,
.init_on_cnt = 0,
.init_off_cnt = 0,
},
};
@@ -116,50 +128,172 @@ static unsigned char bl_extern_get_i2c_bus_str(const char *str)
unsigned char i2c_bus;
if (strncmp(str, "i2c_bus_ao", 10) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_4;
i2c_bus = LCD_EXT_I2C_BUS_4;
else if (strncmp(str, "i2c_bus_a", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_0;
i2c_bus = LCD_EXT_I2C_BUS_0;
else if (strncmp(str, "i2c_bus_b", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_1;
i2c_bus = LCD_EXT_I2C_BUS_1;
else if (strncmp(str, "i2c_bus_c", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_2;
i2c_bus = LCD_EXT_I2C_BUS_2;
else if (strncmp(str, "i2c_bus_d", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_3;
i2c_bus = LCD_EXT_I2C_BUS_3;
else if (strncmp(str, "i2c_bus_0", 10) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_0;
i2c_bus = LCD_EXT_I2C_BUS_0;
else if (strncmp(str, "i2c_bus_1", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_1;
i2c_bus = LCD_EXT_I2C_BUS_1;
else if (strncmp(str, "i2c_bus_2", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_2;
i2c_bus = LCD_EXT_I2C_BUS_2;
else if (strncmp(str, "i2c_bus_3", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_3;
i2c_bus = LCD_EXT_I2C_BUS_3;
else if (strncmp(str, "i2c_bus_4", 9) == 0)
i2c_bus = BL_EXTERN_I2C_BUS_4;
i2c_bus = LCD_EXT_I2C_BUS_4;
else {
i2c_bus = BL_EXTERN_I2C_BUS_MAX;
i2c_bus = LCD_EXT_I2C_BUS_MAX;
BLEXERR("invalid i2c_bus: %s\n", str);
}
return i2c_bus;
}
#define EXT_LEN_MAX 500
static void bl_extern_init_table_dynamic_size_print(
struct bl_extern_config_s *econf, int flag)
{
int i, j, k, max_len;
unsigned char cmd_size;
char *str;
unsigned char *table;
str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL);
if (str == NULL) {
BLEXERR("%s: str malloc error\n", __func__);
return;
}
if (flag) {
pr_info("power on:\n");
table = econf->init_on;
max_len = econf->init_off_cnt;
} else {
pr_info("power off:\n");
table = econf->init_off;
max_len = econf->init_off_cnt;
}
if (table == NULL) {
BLEXERR("init_table %d is NULL\n", flag);
kfree(str);
return;
}
i = 0;
while ((i + 1) < max_len) {
if (table[i] == LCD_EXT_CMD_TYPE_END) {
pr_info(" 0x%02x,%d,\n", table[i], table[i+1]);
break;
}
cmd_size = table[i+1];
k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,",
table[i], cmd_size);
if (cmd_size == 0)
goto init_table_dynamic_print_next;
if (i + 2 + cmd_size > max_len) {
pr_info("cmd_size out of support\n");
break;
}
if (table[i] == LCD_EXT_CMD_TYPE_DELAY) {
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"%d,", table[i+2+j]);
}
} else if (table[i] == LCD_EXT_CMD_TYPE_CMD) {
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"0x%02x,", table[i+2+j]);
}
} else if (table[i] == LCD_EXT_CMD_TYPE_CMD_DELAY) {
for (j = 0; j < (cmd_size - 1); j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"0x%02x,", table[i+2+j]);
}
snprintf(str+k, EXT_LEN_MAX,
"%d,", table[i+cmd_size+1]);
} else {
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX,
"0x%02x,", table[i+2+j]);
}
}
init_table_dynamic_print_next:
pr_info("%s\n", str);
i += (cmd_size + 2);
}
kfree(str);
}
static void bl_extern_init_table_fixed_size_print(
struct bl_extern_config_s *econf, int flag)
{
int i, j, k, max_len;
unsigned char cmd_size;
char *str;
unsigned char *table;
str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL);
if (str == NULL) {
BLEXERR("%s: str malloc error\n", __func__);
return;
}
cmd_size = econf->cmd_size;
if (flag) {
pr_info("power on:\n");
table = econf->init_on;
max_len = econf->init_on_cnt;
} else {
pr_info("power off:\n");
table = econf->init_off;
max_len = econf->init_off_cnt;
}
if (table == NULL) {
BLEXERR("init_table %d is NULL\n", flag);
kfree(str);
return;
}
i = 0;
while ((i + cmd_size) <= max_len) {
k = snprintf(str, EXT_LEN_MAX, " ");
for (j = 0; j < cmd_size; j++) {
k += snprintf(str+k, EXT_LEN_MAX, " 0x%02x",
table[i+j]);
}
pr_info("%s\n", str);
if (table[i] == LCD_EXT_CMD_TYPE_END)
break;
i += cmd_size;
}
kfree(str);
}
static void bl_extern_config_print(void)
{
struct aml_bl_extern_driver_s *bl_extern = aml_bl_extern_get_driver();
struct aml_bl_extern_i2c_dev_s *i2c_dev = aml_bl_extern_i2c_get_dev();
BLEX("%s:\n", __func__);
pr_info("index: %d\n"
"name: %s\n",
bl_extern->config.index,
bl_extern->config.name);
switch (bl_extern->config.type) {
case BL_EXTERN_I2C:
pr_info("index: %d\n"
"name: %s\n"
"type: i2c(%d)\n"
pr_info("type: i2c(%d)\n"
"i2c_addr: 0x%02x\n"
"i2c_bus: %d\n"
"dim_min: %d\n"
"dim_max: %d\n",
bl_extern->config.index,
bl_extern->config.name,
bl_extern->config.type,
bl_extern->config.i2c_addr,
bl_extern->config.i2c_bus,
@@ -175,27 +309,263 @@ static void bl_extern_config_print(void)
} else {
pr_info("invalid i2c device\n");
}
if (bl_extern->config.cmd_size == 0)
break;
pr_info("table_loaded: %d\n"
"cmd_size: %d\n"
"init_on_cnt: %d\n"
"init_off_cnt: %d\n",
bl_extern->config.init_loaded,
bl_extern->config.cmd_size,
bl_extern->config.init_on_cnt,
bl_extern->config.init_off_cnt);
if (bl_extern->config.cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) {
bl_extern_init_table_dynamic_size_print(
&bl_extern->config, 1);
bl_extern_init_table_dynamic_size_print(
&bl_extern->config, 0);
} else {
bl_extern_init_table_fixed_size_print(
&bl_extern->config, 1);
bl_extern_init_table_fixed_size_print(
&bl_extern->config, 0);
}
break;
case BL_EXTERN_SPI:
break;
case BL_EXTERN_MIPI:
pr_info("index: %d\n"
"name: %s\n"
"type: mipi(%d)\n"
pr_info("type: spi(%d)\n"
"dim_min: %d\n"
"dim_max: %d\n",
bl_extern->config.type,
bl_extern->config.dim_min,
bl_extern->config.dim_max);
if (bl_extern->config.cmd_size == 0)
break;
pr_info("table_loaded: %d\n"
"cmd_size: %d\n"
"init_on_cnt: %d\n"
"init_off_cnt: %d\n",
bl_extern->config.init_loaded,
bl_extern->config.cmd_size,
bl_extern->config.init_on_cnt,
bl_extern->config.init_off_cnt);
if (bl_extern->config.cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) {
bl_extern_init_table_dynamic_size_print(
&bl_extern->config, 1);
bl_extern_init_table_dynamic_size_print(
&bl_extern->config, 0);
} else {
bl_extern_init_table_fixed_size_print(
&bl_extern->config, 1);
bl_extern_init_table_fixed_size_print(
&bl_extern->config, 0);
}
break;
case BL_EXTERN_MIPI:
pr_info("type: mipi(%d)\n"
"dim_min: %d\n"
"dim_max: %d\n",
bl_extern->config.index,
bl_extern->config.name,
bl_extern->config.type,
bl_extern->config.dim_min,
bl_extern->config.dim_max);
break;
default:
break;
}
}
static int bl_extern_init_table_dynamic_size_load_dts(
struct device_node *of_node,
struct bl_extern_config_s *extconf, int flag)
{
unsigned char cmd_size, type;
int i = 0, j, val, max_len, step = 0, ret = 0;
unsigned char *table;
char propname[20];
if (flag) {
table = table_init_on_dft;
max_len = BL_EXTERN_INIT_ON_MAX;
sprintf(propname, "init_on");
} else {
table = table_init_off_dft;
max_len = BL_EXTERN_INIT_OFF_MAX;
sprintf(propname, "init_off");
}
if (table == NULL) {
BLEXERR("%s: init_table is null\n", __func__);
return -1;
}
while ((i + 1) < max_len) {
/* type */
ret = of_property_read_u32_index(of_node, propname, i, &val);
if (ret) {
BLEXERR("%s: get %s type failed, step %d\n",
extconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
table[i] = (unsigned char)val;
type = table[i];
/* cmd_size */
ret = of_property_read_u32_index(of_node, propname,
(i+1), &val);
if (ret) {
BLEXERR("%s: get %s cmd_size failed, step %d\n",
extconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
table[i+1] = (unsigned char)val;
cmd_size = table[i+1];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (cmd_size == 0)
goto init_table_dynamic_dts_next;
if ((i + 2 + cmd_size) > max_len) {
BLEXERR("%s: %s cmd_size out of support, step %d\n",
extconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
/* data */
for (j = 0; j < cmd_size; j++) {
ret = of_property_read_u32_index(
of_node, propname, (i+2+j), &val);
if (ret) {
BLEXERR("%s: get %s data failed, step %d\n",
extconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
table[i+1] = 0;
return -1;
}
table[i+2+j] = (unsigned char)val;
}
init_table_dynamic_dts_next:
i += (cmd_size + 2);
step++;
}
if (flag)
extconf->init_on_cnt = i + 2;
else
extconf->init_off_cnt = i + 2;
return 0;
}
static int bl_extern_init_table_fixed_size_load_dts(
struct device_node *of_node,
struct bl_extern_config_s *extconf, int flag)
{
unsigned char cmd_size;
int i = 0, j, val, max_len, step = 0, ret = 0;
unsigned char *table;
char propname[20];
cmd_size = extconf->cmd_size;
if (flag) {
table = table_init_on_dft;
max_len = BL_EXTERN_INIT_ON_MAX;
sprintf(propname, "init_on");
} else {
table = table_init_off_dft;
max_len = BL_EXTERN_INIT_OFF_MAX;
sprintf(propname, "init_off");
}
if (table == NULL) {
BLEXERR("%s: init_table is null\n", __func__);
return -1;
}
while (i < max_len) { /* group detect */
if ((i + cmd_size) > max_len) {
BLEXERR("%s: %s cmd_size out of support, step %d\n",
extconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
return -1;
}
for (j = 0; j < cmd_size; j++) {
ret = of_property_read_u32_index(
of_node, propname, (i+j), &val);
if (ret) {
BLEXERR("%s: get %s failed, step %d\n",
extconf->name, propname, step);
table[i] = LCD_EXT_CMD_TYPE_END;
return -1;
}
table[i+j] = (unsigned char)val;
}
if (table[i] == LCD_EXT_CMD_TYPE_END)
break;
i += cmd_size;
step++;
}
if (flag)
extconf->init_on_cnt = i + cmd_size;
else
extconf->init_off_cnt = i + cmd_size;
return 0;
}
static int bl_extern_tablet_init_dft_malloc(void)
{
table_init_on_dft = kcalloc(BL_EXTERN_INIT_ON_MAX,
sizeof(unsigned char), GFP_KERNEL);
if (table_init_on_dft == NULL) {
BLEXERR("failed to alloc init_on table\n");
return -1;
}
table_init_off_dft = kcalloc(BL_EXTERN_INIT_OFF_MAX,
sizeof(unsigned char), GFP_KERNEL);
if (table_init_off_dft == NULL) {
BLEXERR("failed to alloc init_off table\n");
kfree(table_init_on_dft);
return -1;
}
table_init_on_dft[0] = LCD_EXT_CMD_TYPE_END;
table_init_on_dft[1] = 0;
table_init_off_dft[0] = LCD_EXT_CMD_TYPE_END;
table_init_off_dft[1] = 0;
return 0;
}
static int bl_extern_table_init_save(struct bl_extern_config_s *extconf)
{
if (extconf->init_on_cnt > 0) {
extconf->init_on = kcalloc(extconf->init_on_cnt,
sizeof(unsigned char), GFP_KERNEL);
if (extconf->init_on == NULL) {
BLEXERR("failed to alloc init_on table\n");
return -1;
}
memcpy(extconf->init_on, table_init_on_dft,
extconf->init_off_cnt*sizeof(unsigned char));
}
if (extconf->init_off_cnt > 0) {
extconf->init_off = kcalloc(extconf->init_off_cnt,
sizeof(unsigned char), GFP_KERNEL);
if (extconf->init_off == NULL) {
BLEXERR("failed to alloc init_off table\n");
kfree(extconf->init_on);
return -1;
}
memcpy(extconf->init_off, table_init_off_dft,
extconf->init_off_cnt*sizeof(unsigned char));
}
return 0;
}
static int bl_extern_config_from_dts(struct device_node *np, int index)
{
char propname[20];
@@ -207,7 +577,7 @@ static int bl_extern_config_from_dts(struct device_node *np, int index)
ret = of_property_read_string(np, "i2c_bus", &str);
if (ret == 0)
bl_extern->config.i2c_bus = BL_EXTERN_I2C_BUS_MAX;
bl_extern->config.i2c_bus = LCD_EXT_I2C_BUS_MAX;
else
bl_extern->config.i2c_bus = bl_extern_get_i2c_bus_str(str);
@@ -247,7 +617,7 @@ static int bl_extern_config_from_dts(struct device_node *np, int index)
BLEX("type: %d\n", bl_extern->config.type);
}
if (bl_extern->config.type >= BL_EXTERN_MAX) {
BLEXERR("type num is out of support\n");
BLEXERR("invalid type %d\n", bl_extern->config.type);
return -1;
}
@@ -261,12 +631,15 @@ static int bl_extern_config_from_dts(struct device_node *np, int index)
bl_extern->config.dim_min = temp[1];
}
ret = bl_extern_tablet_init_dft_malloc();
if (ret)
return -1;
switch (bl_extern->config.type) {
case BL_EXTERN_I2C:
if (bl_extern->config.i2c_bus >= BL_EXTERN_I2C_BUS_MAX) {
if (bl_extern->config.i2c_bus >= LCD_EXT_I2C_BUS_MAX) {
BLEXERR("failed to get i2c_bus\n");
} else {
BLEX("%s i2c_bus=%s[%d]\n",
BLEX("%s: i2c_bus=%s[%d]\n",
bl_extern->config.name,
str, bl_extern->config.i2c_bus);
}
@@ -276,19 +649,98 @@ static int bl_extern_config_from_dts(struct device_node *np, int index)
BLEXERR("failed to get i2c_address\n");
} else {
bl_extern->config.i2c_addr = (unsigned char)val;
BLEX("%s i2c_address=0x%02x\n",
BLEX("%s: i2c_address=0x%02x\n",
bl_extern->config.name,
bl_extern->config.i2c_addr);
}
ret = of_property_read_u32(child, "cmd_size", &val);
if (ret) {
BLEX("%s: no cmd_size\n", bl_extern->config.name);
bl_extern->config.cmd_size = 0;
} else {
bl_extern->config.cmd_size = (unsigned char)val;
}
if (bl_debug_print_flag) {
BLEX("%s: cmd_size = %d\n",
bl_extern->config.name,
bl_extern->config.cmd_size);
}
if (bl_extern->config.cmd_size == 0)
break;
if (bl_extern->config.cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) {
ret = bl_extern_init_table_dynamic_size_load_dts(
child, &bl_extern->config, 1);
if (ret)
break;
ret = bl_extern_init_table_dynamic_size_load_dts(
child, &bl_extern->config, 0);
} else {
ret = bl_extern_init_table_fixed_size_load_dts(
child, &bl_extern->config, 1);
if (ret)
break;
ret = bl_extern_init_table_fixed_size_load_dts(
child, &bl_extern->config, 0);
}
if (ret == 0)
bl_extern->config.init_loaded = 1;
break;
case BL_EXTERN_SPI:
ret = of_property_read_u32(child, "cmd_size", &val);
if (ret) {
BLEX("%s: no cmd_size\n", bl_extern->config.name);
bl_extern->config.cmd_size = 0;
} else {
bl_extern->config.cmd_size = (unsigned char)val;
}
if (bl_debug_print_flag) {
BLEX("%s: cmd_size = %d\n",
bl_extern->config.name,
bl_extern->config.cmd_size);
}
if (bl_extern->config.cmd_size == 0)
break;
if (bl_extern->config.cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) {
ret = bl_extern_init_table_dynamic_size_load_dts(
child, &bl_extern->config, 1);
if (ret)
break;
ret = bl_extern_init_table_dynamic_size_load_dts(
child, &bl_extern->config, 0);
} else {
ret = bl_extern_init_table_fixed_size_load_dts(
child, &bl_extern->config, 1);
if (ret)
break;
ret = bl_extern_init_table_fixed_size_load_dts(
child, &bl_extern->config, 0);
}
if (ret == 0)
bl_extern->config.init_loaded = 1;
break;
case BL_EXTERN_MIPI:
break;
default:
break;
}
if (bl_extern->config.init_loaded > 0) {
ret = bl_extern_table_init_save(&bl_extern->config);
if (ret)
goto bl_extern_get_config_err;
}
kfree(table_init_on_dft);
kfree(table_init_off_dft);
return 0;
bl_extern_get_config_err:
kfree(table_init_on_dft);
kfree(table_init_off_dft);
return -1;
}
static int bl_extern_add_driver(void)
@@ -352,8 +804,9 @@ int aml_bl_extern_device_load(int index)
int ret = 0;
bl_extern_config_from_dts(bl_extern_driver.dev->of_node, index);
bl_extern_add_driver();
ret = bl_extern_add_driver();
bl_extern_driver.config_print = bl_extern_config_print;
BLEX("%s OK\n", __func__);
return ret;

View File

@@ -19,13 +19,13 @@ bl_extern{
compatible = "amlogic, bl_extern";
dev_name = "bl_extern";
status = "okay";
i2c_bus = "i2c_bus_d";
extern_0{
index = <0>;
extern_name = "i2c_lp8556";
type = <1>; /** bl_extern_driver type: 1=i2c, 2=spi, 3=mipi */
i2c_address = <0x2c>; /** 7bit i2c address */
i2c_bus = "i2c_bus_d";
dim_max_min = <255 10>;
};

View File

@@ -17,11 +17,9 @@
#ifndef _BL_EXTERN_H_
#define _BL_EXTERN_H_
#include <linux/of.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/amlogic/aml_gpio_consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/amlogic/media/vout/lcd/aml_bl_extern.h>
extern unsigned int bl_debug_print_flag;
#define BLEX(fmt, args...) pr_info("bl extern: "fmt"", ## args)
@@ -42,6 +40,9 @@ extern int bl_extern_i2c_read(struct i2c_client *i2client,
unsigned char *buff, unsigned int len);
extern int bl_ext_default_probe(struct aml_bl_extern_driver_s *bl_ext);
extern int bl_ext_default_remove(struct aml_bl_extern_driver_s *bl_ext);
#ifdef CONFIG_AMLOGIC_BL_EXTERN_I2C_LP8556
extern int i2c_lp8556_probe(void);
extern int i2c_lp8556_remove(void);

View File

@@ -24,6 +24,7 @@
static struct aml_bl_extern_i2c_dev_s *i2c_device;
struct aml_bl_extern_i2c_dev_s *aml_bl_extern_i2c_get_dev(void)
{
return i2c_device;

View File

@@ -34,57 +34,126 @@
static struct bl_extern_config_s *ext_config;
static struct aml_bl_extern_i2c_dev_s *i2c_dev;
#define BL_EXTERN_CMD_SIZE 4
#define BL_EXTERN_CMD_SIZE LCD_EXT_CMD_SIZE_DYNAMIC
static unsigned char init_on_table[] = {
0x00, 0xa2, 0x20, 0x00,
0x00, 0xa5, 0x54, 0x00,
0x00, 0x00, 0xff, 0x00,
0x00, 0x01, 0x05, 0x00,
0x00, 0xa2, 0x20, 0x00,
0x00, 0xa5, 0x54, 0x00,
0x00, 0xa1, 0xb7, 0x00,
0x00, 0xa0, 0xff, 0x00,
0x00, 0x00, 0x80, 0x00,
0xff, 0x00, 0x00, 0x00, /*ending*/
0xc0, 2, 0xa2, 0x20,
0xc0, 2, 0xa5, 0x54,
0xc0, 2, 0x00, 0xff,
0xc0, 2, 0x01, 0x05,
0xc0, 2, 0xa2, 0x20,
0xc0, 2, 0xa5, 0x54,
0xc0, 2, 0xa1, 0xb7,
0xc0, 2, 0xa0, 0xff,
0xc0, 2, 0x00, 0x80,
0xff, 0, /*ending*/
};
static unsigned char init_off_table[] = {
0xff, 0x00, 0x00, 0x00, /*ending*/
0xff, 0, /*ending*/
};
static int i2c_lp8556_power_cmd(unsigned char *init_table)
static int bl_extern_power_cmd_dynamic_size(unsigned char *table, int flag)
{
int i = 0, len;
int ret = 0;
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int delay_ms, ret = 0;
if (flag)
max_len = ext_config->init_on_cnt;
else
max_len = ext_config->init_off_cnt;
BLEX("%s\n", __func__);
if (ext_config == NULL) {
BLEXERR("invalid ext_config\n");
return -1;
}
if (i2c_dev == NULL) {
BLEXERR("invalid i2c device\n");
return -1;
}
len = BL_EXTERN_CMD_SIZE;
while (i <= BL_EXTERN_INIT_TABLE_MAX) {
if (init_table[i] == BL_EXTERN_INIT_END) {
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
} else if (init_table[i] == BL_EXTERN_INIT_NONE) {
/* do nothing, only for delay */
} else if (init_table[i] == BL_EXTERN_INIT_CMD) {
ret = bl_extern_i2c_write(i2c_dev->client,
&init_table[i+1], (len-2));
} else {
BLEXERR("%s: %s(%d): power_type %d is invalid\n",
__func__, ext_config->name,
ext_config->index, ext_config->type);
if (bl_debug_print_flag) {
BLEX("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, table[i+1]);
}
if (init_table[i+len-1] > 0)
mdelay(init_table[i+len-1]);
i += len;
cmd_size = table[i+1];
if (cmd_size == 0)
goto power_cmd_dynamic_next;
if ((i + 2 + cmd_size) > max_len)
break;
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += table[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = bl_extern_i2c_write(i2c_dev->client,
&table[i+2], cmd_size);
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = bl_extern_i2c_write(i2c_dev->client,
&table[i+2], (cmd_size-1));
if (table[i+cmd_size+1] > 0)
mdelay(table[i+cmd_size+1]);
} else {
BLEXERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, type);
}
power_cmd_dynamic_next:
i += (cmd_size + 2);
step++;
}
return ret;
}
static int bl_extern_power_cmd_fixed_size(unsigned char *table, int flag)
{
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int delay_ms, ret = 0;
cmd_size = ext_config->cmd_size;
if (cmd_size < 2) {
BLEXERR("%s: invalid cmd_size %d\n", __func__, cmd_size);
return -1;
}
if (flag)
max_len = ext_config->init_on_cnt;
else
max_len = ext_config->init_off_cnt;
while ((i + cmd_size) <= max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (bl_debug_print_flag) {
BLEX("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, cmd_size);
}
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < (cmd_size - 1); j++)
delay_ms += table[i+1+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = bl_extern_i2c_write(i2c_dev->client,
&table[i+1], (cmd_size-1));
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = bl_extern_i2c_write(i2c_dev->client,
&table[i+1], (cmd_size-2));
if (table[i+cmd_size-1] > 0)
mdelay(table[i+cmd_size-1]);
} else {
BLEXERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, type);
}
i += cmd_size;
step++;
}
return ret;
@@ -92,19 +161,33 @@ static int i2c_lp8556_power_cmd(unsigned char *init_table)
static int i2c_lp8556_power_ctrl(int flag)
{
unsigned char *table;
unsigned char cmd_size;
int ret = 0;
BLEX("%s\n", __func__);
if (ext_config == NULL) {
BLEXERR("invalid ext_config\n");
return -1;
}
cmd_size = ext_config->cmd_size;
if (flag)
ret = i2c_lp8556_power_cmd(init_on_table);
table = ext_config->init_on;
else
ret = i2c_lp8556_power_cmd(init_off_table);
table = ext_config->init_off;
if (cmd_size < 1) {
BLEXERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
return -1;
}
if (i2c_dev == NULL) {
BLEXERR("invalid i2c device\n");
return -1;
}
if (cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC)
ret = bl_extern_power_cmd_dynamic_size(table, flag);
else
ret = bl_extern_power_cmd_fixed_size(table, flag);
BLEX("%s: %s(%d): %d\n",
__func__, ext_config->name, ext_config->index, flag);
@@ -162,6 +245,12 @@ static int i2c_lp8556_update(void)
bl_extern->device_power_off = i2c_lp8556_power_off;
bl_extern->device_bri_update = i2c_lp8556_set_level;
bl_extern->config.cmd_size = BL_EXTERN_CMD_SIZE;
bl_extern->config.init_on = init_on_table;
bl_extern->config.init_on_cnt = sizeof(init_on_table);
bl_extern->config.init_off = init_off_table;
bl_extern->config.init_off_cnt = sizeof(init_off_table);
return 0;
}
@@ -177,6 +266,9 @@ int i2c_lp8556_probe(void)
int i2c_lp8556_remove(void)
{
i2c_dev = NULL;
ext_config = NULL;
return 0;
}

View File

@@ -41,9 +41,16 @@ static int mipi_lt070me05_power_off(void)
return 0;
}
/******************** mipi command ********************
*format: data_type, num, data....
*special: data_type=0xff, num<0xff means delay ms, num=0xff means ending.
/******************** mipi command ********************/
/* format: data_type, cmd_size, data.... */
/* data_type=0xff,
* 0 < cmd_size < 0xff means delay ms,
* cmd_size=0 or 0xff means ending.
* data_type=0xf0, for gpio control
* data0=gpio_index, data1=gpio_value.
* data0=gpio_index, data1=gpio_value, data2=delay.
* data_type=0xfd, for delay ms
* data0=delay, data_1=delay, ..., data_n=delay.
*/
static int mipi_lt070me05_set_level(unsigned int level)
{

View File

@@ -576,6 +576,7 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf,
LCDPR("power_on step:\n");
i = 0;
while (i < LCD_PWR_STEP_MAX) {
pconf->lcd_power->power_on_step_max = i;
len += 5;
ret = lcd_unifykey_len_check(key_len, len);
if (ret < 0) {
@@ -627,6 +628,7 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf,
p += (5*(i + 1));
j = 0;
while (j < LCD_PWR_STEP_MAX) {
pconf->lcd_power->power_off_step_max = j;
len += 5;
ret = lcd_unifykey_len_check(key_len, len);
if (ret < 0) {

View File

@@ -15,6 +15,16 @@ config AMLOGIC_LCD_EXTERN_I2C_T5800Q
through the i2c interface to write data to the LCD,
make its initialization
config AMLOGIC_LCD_EXTERN_I2C_ANX6862_7911
bool "lcd external i2c ANX6862_7911 init driver"
default n
depends on AMLOGIC_LCD_EXTERN
help
Amlogic LCD external i2c_ANX6862_7911 init driver support
Once the power on, according to the timing requirements,
through the i2c interface to write data to the LCD,
make its initialization
config AMLOGIC_LCD_EXTERN_I2C_DLPC3439
bool "lcd external i2c DLPC3439 init driver"
default n
@@ -35,16 +45,6 @@ config AMLOGIC_LCD_EXTERN_I2C_ANX6345
through the i2c interface to write data to the LCD,
make its initialization
config AMLOGIC_LCD_EXTERN_I2C_TC101
bool "lcd external i2c TC101 init driver"
default n
depends on AMLOGIC_LCD_EXTERN
help
Amlogic LCD external i2c_TC101 init driver support
Once the power on, according to the timing requirements,
through the i2c interface to write data to the LCD,
make its initialization
config AMLOGIC_LCD_EXTERN_SPI_LD070WS2
bool "lcd external spi LD070WS2 init driver"
default n

View File

@@ -1,5 +1,6 @@
obj-$(CONFIG_AMLOGIC_LCD_EXTERN) += lcd_extern.o ext_default.o mipi_default.o ext_i2c_dev.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q) += i2c_T5800Q.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6862_7911) += i2c_ANX6862_7911.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439) += i2c_DLPC3439.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_SPI_LD070WS2) += spi_LD070WS2.o
obj-$(CONFIG_AMLOGIC_LCD_EXTERN_MIPI_KD080D13) += mipi_KD080D13.o

View File

@@ -28,7 +28,6 @@
#include "lcd_extern.h"
#define LCD_EXTERN_NAME "ext_default"
#define LCD_EXTERN_TYPE LCD_EXTERN_MAX
static struct lcd_extern_config_s *ext_config;
@@ -165,134 +164,150 @@ static int lcd_extern_reg_write(unsigned char reg, unsigned char value)
return ret;
}
static int lcd_extern_power_cmd_dynamic_size(unsigned char *init_table,
int flag)
static int lcd_extern_power_cmd_dynamic_size(unsigned char *table, int flag)
{
int i = 0, step = 0, max_len = 0;
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int ret = 0;
int delay_ms, ret = 0;
if (flag)
max_len = LCD_EXTERN_INIT_ON_MAX;
max_len = ext_config->table_init_on_cnt;
else
max_len = LCD_EXTERN_INIT_OFF_MAX;
max_len = ext_config->table_init_off_cnt;
switch (ext_config->type) {
case LCD_EXTERN_I2C:
while ((i + 2) < max_len) {
type = init_table[i];
if (type == LCD_EXTERN_INIT_END)
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_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]);
__func__, step, type, table[i+1]);
}
cmd_size = init_table[i+1];
cmd_size = table[i+1];
if (cmd_size == 0)
goto power_cmd_dynamic_i2c_next;
if ((i + 2 + cmd_size) > max_len)
break;
if (type == LCD_EXTERN_INIT_NONE) {
if (cmd_size < 1) {
EXTERR("step %d: invalid cmd_size %d\n",
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_GPIO) {
if (cmd_size < 2) {
EXTERR(
"step %d: invalid cmd_size %d for GPIO\n",
step, cmd_size);
i += (cmd_size + 2);
step++;
continue;
goto power_cmd_dynamic_i2c_next;
}
/* 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 (table[i+2] < LCD_GPIO_MAX) {
lcd_extern_gpio_set(table[i+2],
table[i+3]);
}
if (init_table[i+2] < LCD_GPIO_MAX) {
lcd_extern_gpio_set(init_table[i+2],
init_table[i+3]);
if (cmd_size > 2) {
if (table[i+4] > 0)
mdelay(table[i+4]);
}
if (init_table[i+4] > 0)
mdelay(init_table[i+4]);
} else if (type == LCD_EXTERN_INIT_CMD) {
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += table[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
if (i2c0_dev == NULL) {
EXTERR("invalid i2c0 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c0_dev->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) {
&table[i+2], cmd_size);
} else if (type == LCD_EXT_CMD_TYPE_CMD2) {
if (i2c1_dev == NULL) {
EXTERR("invalid i2c1 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c1_dev->client,
&init_table[i+2], (cmd_size-1));
if (init_table[i+cmd_size+1] > 0)
mdelay(init_table[i+cmd_size+1]);
&table[i+2], cmd_size);
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
if (i2c0_dev == NULL) {
EXTERR("invalid i2c0 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c0_dev->client,
&table[i+2], (cmd_size-1));
if (table[i+cmd_size+1] > 0)
mdelay(table[i+cmd_size+1]);
} else if (type == LCD_EXT_CMD_TYPE_CMD2_DELAY) {
if (i2c1_dev == NULL) {
EXTERR("invalid i2c1 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c1_dev->client,
&table[i+2], (cmd_size-1));
if (table[i+cmd_size+1] > 0)
mdelay(table[i+cmd_size+1]);
} else {
EXTERR("%s: %s(%d): type %d invalid\n",
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, ext_config->type);
ext_config->index, type);
}
power_cmd_dynamic_i2c_next:
i += (cmd_size + 2);
step++;
}
break;
case LCD_EXTERN_SPI:
while ((i + 2) < max_len) {
type = init_table[i];
if (type == LCD_EXTERN_INIT_END)
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_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]);
__func__, step, type, table[i+1]);
}
cmd_size = init_table[i+1];
cmd_size = table[i+1];
if (cmd_size == 0)
goto power_cmd_dynamic_spi_next;
if ((i + 2 + cmd_size) > max_len)
break;
if (type == LCD_EXTERN_INIT_NONE) {
if (cmd_size < 1) {
EXTERR("step %d: invalid cmd_size %d\n",
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothingy */
} else if (type == LCD_EXT_CMD_TYPE_GPIO) {
if (cmd_size < 2) {
EXTERR(
"step %d: invalid cmd_size %d for GPIO\n",
step, cmd_size);
i += (cmd_size + 2);
step++;
continue;
goto power_cmd_dynamic_spi_next;
}
/* 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 (table[i+2] < LCD_GPIO_MAX) {
lcd_extern_gpio_set(table[i+2],
table[i+3]);
}
if (init_table[i+2] < LCD_GPIO_MAX) {
lcd_extern_gpio_set(init_table[i+2],
init_table[i+3]);
if (cmd_size > 2) {
if (table[i+4] > 0)
mdelay(table[i+4]);
}
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 if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += table[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = lcd_extern_spi_write(&table[i+2],
cmd_size);
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = lcd_extern_spi_write(&table[i+2],
(cmd_size-1));
if (table[i+cmd_size+1] > 0)
mdelay(table[i+cmd_size+1]);
} else {
EXTERR("%s: %s(%d): type %d invalid\n",
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, ext_config->type);
ext_config->index, type);
}
power_cmd_dynamic_spi_next:
i += (cmd_size + 2);
step++;
}
@@ -307,86 +322,130 @@ static int lcd_extern_power_cmd_dynamic_size(unsigned char *init_table,
return ret;
}
static int lcd_extern_power_cmd_fixed_size(unsigned char *init_table, int flag)
static int lcd_extern_power_cmd_fixed_size(unsigned char *table, int flag)
{
int i = 0, step = 0, max_len = 0;
int i = 0, j, 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;
int delay_ms, ret = 0;
cmd_size = ext_config->cmd_size;
if (cmd_size < 2) {
EXTERR("%s: invalid cmd_size %d\n", __func__, cmd_size);
return -1;
}
if (flag)
max_len = ext_config->table_init_on_cnt;
else
max_len = ext_config->table_init_off_cnt;
switch (ext_config->type) {
case LCD_EXTERN_I2C:
while ((i + cmd_size) <= max_len) {
type = init_table[i];
if (type == LCD_EXTERN_INIT_END)
type = table[i];
if (type == LCD_EXT_CMD_TYPE_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]);
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_GPIO) {
if (table[i+1] < LCD_GPIO_MAX) {
lcd_extern_gpio_set(table[i+1],
table[i+2]);
}
} else if (type == LCD_EXTERN_INIT_CMD) {
if (cmd_size > 3) {
if (table[i+3] > 0)
mdelay(table[i+3]);
}
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < (cmd_size - 1); j++)
delay_ms += table[i+1+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
if (i2c0_dev == NULL) {
EXTERR("invalid i2c0 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c0_dev->client,
&init_table[i+1], (cmd_size-2));
} else if (type == LCD_EXTERN_INIT_CMD2) {
&table[i+1], (cmd_size-1));
} else if (type == LCD_EXT_CMD_TYPE_CMD2) {
if (i2c1_dev == NULL) {
EXTERR("invalid i2c1 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c1_dev->client,
&init_table[i+1], (cmd_size-2));
&table[i+1], (cmd_size-1));
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
if (i2c0_dev == NULL) {
EXTERR("invalid i2c0 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c0_dev->client,
&table[i+1], (cmd_size-2));
if (table[i+cmd_size-1] > 0)
mdelay(table[i+cmd_size-1]);
} else if (type == LCD_EXT_CMD_TYPE_CMD2_DELAY) {
if (i2c1_dev == NULL) {
EXTERR("invalid i2c1 device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c1_dev->client,
&table[i+1], (cmd_size-2));
if (table[i+cmd_size-1] > 0)
mdelay(table[i+cmd_size-1]);
} else {
EXTERR("%s: %s(%d): type %d invalid\n",
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, ext_config->type);
ext_config->index, 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 + cmd_size) <= max_len) {
type = init_table[i];
if (type == LCD_EXTERN_INIT_END)
type = table[i];
if (type == LCD_EXT_CMD_TYPE_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]);
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_GPIO) {
if (table[i+1] < LCD_GPIO_MAX) {
lcd_extern_gpio_set(table[i+1],
table[i+2]);
}
} else if (type == LCD_EXTERN_INIT_CMD) {
ret = lcd_extern_spi_write(&init_table[i+1],
if (cmd_size > 3) {
if (table[i+3] > 0)
mdelay(table[i+3]);
}
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < (cmd_size - 1); j++)
delay_ms += table[i+1+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = lcd_extern_spi_write(&table[i+1],
(cmd_size-1));
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = lcd_extern_spi_write(&table[i+1],
(cmd_size-2));
if (table[i+cmd_size-1] > 0)
mdelay(table[i+cmd_size-1]);
} else {
EXTERR("%s: %s(%d): type %d invalid\n",
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, ext_config->type);
ext_config->index, type);
}
if (init_table[i+cmd_size-1] > 0)
mdelay(init_table[i+cmd_size-1]);
i += cmd_size;
step++;
}
@@ -403,31 +462,31 @@ static int lcd_extern_power_cmd_fixed_size(unsigned char *init_table, int flag)
static int lcd_extern_power_ctrl(int flag)
{
unsigned char *init_table;
unsigned char *table;
unsigned char cmd_size;
int ret = 0;
if (ext_config->type == LCD_EXTERN_SPI)
spi_gpio_init();
if (flag)
init_table = ext_config->table_init_on;
else
init_table = ext_config->table_init_off;
cmd_size = ext_config->cmd_size;
if (flag)
table = ext_config->table_init_on;
else
table = ext_config->table_init_off;
if (cmd_size < 1) {
EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
return -1;
}
if (init_table == NULL) {
if (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);
if (cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC)
ret = lcd_extern_power_cmd_dynamic_size(table, flag);
else
ret = lcd_extern_power_cmd_fixed_size(init_table, flag);
ret = lcd_extern_power_cmd_fixed_size(table, flag);
if (ext_config->type == LCD_EXTERN_SPI)
spi_gpio_off();
@@ -458,13 +517,17 @@ static int lcd_extern_power_off(void)
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
EXTERR("%s: driver is null\n", LCD_EXTERN_NAME);
return -1;
}
if (ext_drv->config->table_init_loaded == 0) {
EXTERR("%s: tablet_init is invalid\n", ext_drv->config->name);
return -1;
}
if (ext_drv->config->type == LCD_EXTERN_SPI) {
ext_drv->config->spi_delay_us =
1000000 / ext_drv->config->spi_clk_freq;
1000 / ext_drv->config->spi_clk_freq;
}
ext_drv->reg_read = lcd_extern_reg_read;
@@ -483,7 +546,7 @@ int aml_lcd_extern_default_probe(struct aml_lcd_extern_driver_s *ext_drv)
switch (ext_config->type) {
case LCD_EXTERN_I2C:
if (ext_config->i2c_addr < LCD_EXTERN_I2C_ADDR_INVALID) {
if (ext_config->i2c_addr < LCD_EXT_I2C_ADDR_INVALID) {
i2c0_dev = lcd_extern_get_i2c_device(
ext_config->i2c_addr);
if (i2c0_dev == NULL) {
@@ -493,7 +556,7 @@ int aml_lcd_extern_default_probe(struct aml_lcd_extern_driver_s *ext_drv)
EXTPR("get i2c0 device: %s, addr 0x%02x OK\n",
i2c0_dev->name, i2c0_dev->client->addr);
}
if (ext_config->i2c_addr2 < LCD_EXTERN_I2C_ADDR_INVALID) {
if (ext_config->i2c_addr2 < LCD_EXT_I2C_ADDR_INVALID) {
i2c1_dev = lcd_extern_get_i2c_device(
ext_config->i2c_addr2);
if (i2c1_dev == NULL) {

View File

@@ -0,0 +1,523 @@
/*
* drivers/amlogic/media/vout/lcd/lcd_extern/i2c_ANX6862_7911.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/amlogic/i2c-amlogic.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
#include "lcd_extern.h"
#define LCD_EXTERN_NAME "i2c_ANX6862_7911"
#define LCD_EXTERN_I2C_ADDR (0x20 >> 1) /* ANX6862 7bit address */
#define LCD_EXTERN_I2C_ADDR2 (0x74 >> 1) /* ANX7911 7bit address */
static struct lcd_extern_config_s *ext_config;
static struct aml_lcd_extern_i2c_dev_s *i2c0_dev;
static struct aml_lcd_extern_i2c_dev_s *i2c1_dev;
static unsigned char ANX6862_NVM_wr[] = {0xff, 0x80};
static unsigned char ANX7911_NVM_wr[] = {0x00, 0x0a};
#define ANX6862_REG_CNT 12
#define ANX7911_REG_CNT 23
#if 0
static unsigned char ANX6862_7911_init[] = {
0x00, 3, 0x01, 0x2b, 0,
0x00, 3, 0x02, 0x05, 0,
0x00, 3, 0x03, 0x00, 0,
0x00, 3, 0x04, 0x00, 0,
0x00, 3, 0x05, 0x0c, 0,
0x00, 3, 0x06, 0x04, 0,
0x00, 3, 0x07, 0x21, 0,
0x00, 3, 0x08, 0x0e, 0,
0x00, 3, 0x09, 0x04, 0,
0x00, 3, 0x0a, 0x00, 0,
0x00, 3, 0x0b, 0x04, 0,
0x00, 3, 0xff, 0x00, 100,
0x01, 3, 0x01, 0xca, 0,
0x01, 3, 0x02, 0x3b, 0,
0x01, 3, 0x03, 0x33, 0,
0x01, 3, 0x04, 0x05, 0,
0x01, 3, 0x05, 0x2c, 0,
0x01, 3, 0x06, 0xf2, 0,
0x01, 3, 0x07, 0x9c, 0,
0x01, 3, 0x08, 0x1b, 0,
0x01, 3, 0x09, 0x82, 0,
0x01, 3, 0x0a, 0x3d, 0,
0x01, 3, 0x0b, 0x20, 0,
0x01, 3, 0x0c, 0x11, 0,
0x01, 3, 0x0d, 0xc4, 0,
0x01, 3, 0x0e, 0x1a, 0,
0x01, 3, 0x0f, 0x31, 0,
0x01, 3, 0x10, 0x4c, 0,
0x01, 3, 0x11, 0x12, 0,
0x01, 3, 0x12, 0x90, 0,
0x01, 3, 0x13, 0xf7, 0,
0x01, 3, 0x14, 0x0c, 0,
0x01, 3, 0x15, 0x20, 0,
0x01, 3, 0x16, 0x13, 0,
0xff, 0,
};
#endif
static int lcd_extern_reg_read(unsigned char reg, unsigned char *buf)
{
struct aml_lcd_extern_i2c_dev_s *i2c_dev;
unsigned char tmp;
int ret = 0;
tmp = reg;
if (ext_config->addr_sel)
i2c_dev = i2c1_dev;
else
i2c_dev = i2c0_dev;
if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
lcd_extern_i2c_read(i2c_dev->client, &tmp, 1);
buf[0] = tmp;
return ret;
}
static int lcd_extern_reg_write(unsigned char reg, unsigned char value)
{
struct aml_lcd_extern_i2c_dev_s *i2c_dev;
unsigned char tmp[2];
int ret = 0;
tmp[0] = reg;
tmp[1] = value;
if (ext_config->addr_sel)
i2c_dev = i2c1_dev;
else
i2c_dev = i2c0_dev;
if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
lcd_extern_i2c_write(i2c_dev->client, tmp, 2);
return ret;
}
static int lcd_extern_power_cmd_dynamic_size(unsigned char *table,
unsigned char flag)
{
int i = 0, j, step = 0, max_len;
unsigned char type, cmd_size, type_chk, type_other;
struct aml_lcd_extern_i2c_dev_s *i2c_dev;
int delay_bypass, delay_ms, ret = 0;
if (table == NULL)
return -1;
max_len = ext_config->table_init_on_cnt;
if (flag) {
i2c_dev = i2c1_dev;
type_chk = LCD_EXT_CMD_TYPE_CMD2;
type_other = LCD_EXT_CMD_TYPE_CMD;
} else {
i2c_dev = i2c0_dev;
type_chk = LCD_EXT_CMD_TYPE_CMD;
type_other = LCD_EXT_CMD_TYPE_CMD2;
}
if (i2c_dev == NULL) {
EXTERR("invalid i2c%d device\n", flag);
return -1;
}
delay_bypass = 0;
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
cmd_size = table[i+1];
if (cmd_size == 0)
goto power_cmd_dynamic_next;
if ((i + 2 + cmd_size) > max_len)
break;
if (type == type_chk) {
if (lcd_debug_print_flag) {
EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, table[i+1]);
}
ret = lcd_extern_i2c_write(i2c_dev->client,
&table[i+2], cmd_size);
delay_bypass = 0;
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
if (delay_bypass)
goto power_cmd_dynamic_next;
if (lcd_debug_print_flag) {
EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, table[i+1]);
}
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += table[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == type_other) {
delay_bypass = 1;
} else {
delay_bypass = 1;
EXTERR("%s(%d: %s): type 0x%02x invalid\n",
__func__, ext_config->index,
ext_config->name, type);
}
power_cmd_dynamic_next:
i += (cmd_size + 2);
step++;
}
return ret;
}
static int lcd_extern_power_cmd_fixed_size(unsigned char *table,
unsigned char flag)
{
int i = 0, j, step = 0, max_len;
unsigned char type, cmd_size, type_chk, type_other;
struct aml_lcd_extern_i2c_dev_s *i2c_dev;
int delay_bypass, delay_ms, ret = 0;
if (table == NULL)
return -1;
cmd_size = ext_config->cmd_size;
max_len = ext_config->table_init_on_cnt;
if (flag) {
i2c_dev = i2c1_dev;
type_chk = LCD_EXT_CMD_TYPE_CMD2;
type_other = LCD_EXT_CMD_TYPE_CMD;
} else {
i2c_dev = i2c0_dev;
type_chk = LCD_EXT_CMD_TYPE_CMD;
type_other = LCD_EXT_CMD_TYPE_CMD2;
}
if (i2c_dev == NULL) {
EXTERR("invalid i2c%d device\n", flag);
return -1;
}
if (cmd_size < 2) {
EXTERR("%s: invalid cmd_size %d\n", __func__, cmd_size);
return -1;
}
delay_bypass = 0;
while ((i + cmd_size) <= max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (type == type_chk) {
if (lcd_debug_print_flag) {
EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, cmd_size);
}
ret = lcd_extern_i2c_write(i2c_dev->client,
&table[i+1], (cmd_size-2));
delay_bypass = 0;
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
if (delay_bypass)
goto power_cmd_fixed_next;
if (lcd_debug_print_flag) {
EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, cmd_size);
}
delay_ms = 0;
for (j = 0; j < (cmd_size - 1); j++)
delay_ms += table[i+1+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == type_other) {
delay_bypass = 1;
} else {
delay_bypass = 1;
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, type);
}
power_cmd_fixed_next:
i += cmd_size;
step++;
}
return ret;
}
static int lcd_extern_power_cmd(unsigned char flag)
{
unsigned char *table;
unsigned char cmd_size;
int ret = 0;
table = ext_config->table_init_on;
cmd_size = ext_config->cmd_size;
if (cmd_size < 1) {
EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
return -1;
}
if (table == NULL) {
EXTERR("%s: init_on_table is NULL\n", __func__);
return -1;
}
if (cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC)
ret = lcd_extern_power_cmd_dynamic_size(table, flag);
else
ret = lcd_extern_power_cmd_fixed_size(table, flag);
EXTPR("%s: %s(%d): %d\n",
__func__, ext_config->name, ext_config->index, flag);
return ret;
}
static int lcd_extern_check_reg_dynamic_size(unsigned char *table,
unsigned char *chk_table, int cnt, unsigned char flag)
{
int i = 0, step = 0, max_len;
unsigned char type, cmd_size, type_chk, reg;
int ret = 0;
if (table == NULL)
return -1;
max_len = ext_config->table_init_on_cnt;
type_chk = (flag) ? LCD_EXT_CMD_TYPE_CMD2 : LCD_EXT_CMD_TYPE_CMD;
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
cmd_size = table[i+1];
if (cmd_size == 0) {
i += 2;
continue;
}
if ((i + 2 + cmd_size) > max_len)
break;
if (type == type_chk) {
reg = table[i+2];
if (lcd_debug_print_flag) {
EXTPR(
"%s: step %d: reg 0x%02x, val 0x%02x,0x%02x\n",
__func__, step,
reg, table[i+3], chk_table[reg]);
}
if (chk_table[reg] != table[i+3])
return -1;
}
i += (cmd_size + 2);
step++;
}
return ret;
}
static int lcd_extern_check_reg_fixed_size(unsigned char *table,
unsigned char *chk_table, int cnt, unsigned char flag)
{
int i = 0, step = 0, max_len;
unsigned char type, cmd_size, type_chk, reg;
cmd_size = ext_config->cmd_size;
max_len = ext_config->table_init_on_cnt;
type_chk = (flag) ? LCD_EXT_CMD_TYPE_CMD2 : LCD_EXT_CMD_TYPE_CMD;
while ((i + cmd_size) <= max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (type == type_chk) {
reg = table[i+1];
if (lcd_debug_print_flag) {
EXTPR(
"%s: step %d: reg 0x%02x, val 0x%02x,0x%02x\n",
__func__, step,
reg, table[i+2], chk_table[reg]);
}
if (chk_table[reg] != table[i+2])
return -1;
}
i += cmd_size;
step++;
}
return 0;
}
static int lcd_extern_init_check(unsigned char flag)
{
unsigned char *table, *chk_table, cmd_size;
int cnt, ret = 0;
table = ext_config->table_init_on;
cmd_size = ext_config->cmd_size;
cnt = (flag) ? ANX7911_REG_CNT : ANX6862_REG_CNT;
if (cmd_size < 1) {
EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
return -1;
}
if (table == NULL) {
EXTERR("%s: init_table %d is NULL\n", __func__, flag);
return -1;
}
chk_table = kcalloc(cnt, sizeof(unsigned char), GFP_KERNEL);
if (chk_table == NULL) {
EXTERR("%s: failed to alloc chk_table, not enough memory\n",
LCD_EXTERN_NAME);
return -1;
}
memset(chk_table, 0, cnt);
ret = lcd_extern_i2c_read(i2c0_dev->client, chk_table, cnt);
if (ret) {
EXTERR("%s: i2c read error\n", __func__);
return -1;
}
if (cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) {
ret = lcd_extern_check_reg_dynamic_size(table, chk_table,
cnt, flag);
} else {
ret = lcd_extern_check_reg_fixed_size(table, chk_table,
cnt, flag);
}
return ret;
}
static int lcd_extern_power_on(void)
{
int ret;
lcd_extern_pinmux_set(1);
/* check voltage is init or not */
/* step1: ANX6862 */
if (i2c0_dev == NULL) {
EXTERR("%s: invalid i2c0_dev\n", __func__);
return -1;
}
ret = lcd_extern_init_check(0);
if (ret) {
EXTPR("ANX6862: need init voltage and NVM write\n");
/* init voltage */
lcd_extern_power_cmd(0);
/* NVM write */
lcd_extern_i2c_write(i2c0_dev->client, ANX6862_NVM_wr, 2);
}
/* step2: ANX7911 */
if (i2c1_dev == NULL) {
EXTERR("%s: invalid i2c1_dev\n", __func__);
return -1;
}
ret = lcd_extern_init_check(1);
if (ret) {
EXTPR("ANX7911: need init voltage and NVM write\n");
/* init voltage */
lcd_extern_power_cmd(1);
/* NVM write */
lcd_extern_i2c_write(i2c1_dev->client, ANX7911_NVM_wr, 2);
}
EXTPR("%s\n", __func__);
return ret;
}
static int lcd_extern_power_off(void)
{
lcd_extern_pinmux_set(0);
return 0;
}
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
return -1;
}
if (ext_drv->config->table_init_loaded == 0) {
EXTERR("%s: tablet_init is invalid\n", ext_drv->config->name);
return -1;
}
ext_drv->reg_read = lcd_extern_reg_read;
ext_drv->reg_write = lcd_extern_reg_write;
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
return 0;
}
int aml_lcd_extern_i2c_ANX6862_7911_probe(
struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
ext_config = ext_drv->config;
i2c0_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr);
if (i2c0_dev == NULL) {
EXTERR("invalid i2c0 device\n");
return -1;
}
EXTPR("get i2c device: %s, addr 0x%02x OK\n",
i2c0_dev->name, i2c0_dev->client->addr);
i2c1_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr2);
if (i2c1_dev == NULL) {
EXTERR("invalid i2c1 device\n");
i2c0_dev = NULL;
return -1;
}
EXTPR("get i2c1 device: %s, addr 0x%02x OK\n",
i2c1_dev->name, i2c1_dev->client->addr);
ret = lcd_extern_driver_update(ext_drv);
if (lcd_debug_print_flag)
EXTPR("%s: %d\n", __func__, ret);
return ret;
}
int aml_lcd_extern_i2c_ANX6862_7911_remove(void)
{
i2c0_dev = NULL;
i2c1_dev = NULL;
ext_config = NULL;
return 0;
}

View File

@@ -93,14 +93,14 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
if (ext_drv == NULL) {
EXTERR("%s: driver is null\n", LCD_EXTERN_NAME);
return -1;
}
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
return ret;
}

View File

@@ -37,78 +37,162 @@
static struct lcd_extern_config_s *ext_config;
static struct aml_lcd_extern_i2c_dev_s *i2c_dev;
#define LCD_EXTERN_CMD_SIZE 9
#define LCD_EXTERN_CMD_SIZE LCD_EXT_CMD_SIZE_DYNAMIC
static unsigned char init_on_table[] = {
0x00, 0x20, 0x01, 0x02, 0x00, 0x40, 0xFF, 0x00, 0x00,
0x00, 0x80, 0x02, 0x00, 0x40, 0x62, 0x51, 0x73, 0x00,
0x00, 0x61, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xC1, 0x05, 0x0F, 0x00, 0x08, 0x70, 0x00, 0x00,
0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x3D, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0xED, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, /* delay 10ms */
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
0xc0, 7, 0x20, 0x01, 0x02, 0x00, 0x40, 0xFF, 0x00,
0xc0, 7, 0x80, 0x02, 0x00, 0x40, 0x62, 0x51, 0x73,
0xc0, 7, 0x61, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 7, 0xC1, 0x05, 0x0F, 0x00, 0x08, 0x70, 0x00,
0xc0, 7, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 7, 0x3D, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00,
0xc0, 7, 0xED, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00,
0xc0, 7, 0x23, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfd, 1, 10, /* delay 10ms */
0xff, 0, /* ending */
};
static unsigned char init_off_table[] = {
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */
0xff, 0, /* ending */
};
static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
static int lcd_extern_power_cmd_dynamic_size(unsigned char *table, int flag)
{
int i = 0, max_len = 0, step = 0;
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 (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;
}
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int delay_ms, ret = 0;
if (flag)
max_len = LCD_EXTERN_INIT_ON_MAX;
max_len = ext_config->table_init_on_cnt;
else
max_len = LCD_EXTERN_INIT_OFF_MAX;
max_len = ext_config->table_init_off_cnt;
while ((i + cmd_size) <= max_len) {
if (init_table[i] == LCD_EXTERN_INIT_END)
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (lcd_debug_print_flag) {
EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, init_table[i], cmd_size);
__func__, step, type, table[i+1]);
}
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]);
cmd_size = table[i+1];
if (cmd_size == 0)
goto power_cmd_dynamic_next;
if ((i + 2 + cmd_size) > max_len)
break;
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_GPIO) {
if (cmd_size < 2) {
EXTERR(
"step %d: invalid cmd_size %d for GPIO\n",
step, cmd_size);
goto power_cmd_dynamic_next;
}
} else if (init_table[i] == LCD_EXTERN_INIT_CMD) {
if (table[i+2] < LCD_GPIO_MAX)
lcd_extern_gpio_set(table[i+2], table[i+3]);
if (cmd_size > 2) {
if (table[i+4] > 0)
mdelay(table[i+4]);
}
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += table[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c_dev->client,
&init_table[i+1], (cmd_size-2));
&table[i+2], cmd_size);
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c_dev->client,
&table[i+2], (cmd_size-1));
if (table[i+cmd_size+1] > 0)
mdelay(table[i+cmd_size+1]);
} else {
EXTERR("%s(%d: %s): power_type %d is invalid\n",
__func__, ext_config->index,
ext_config->name, ext_config->type);
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, type);
}
if (init_table[i+cmd_size-1] > 0)
mdelay(init_table[i+cmd_size-1]);
power_cmd_dynamic_next:
i += (cmd_size + 2);
step++;
}
return ret;
}
static int lcd_extern_power_cmd_fixed_size(unsigned char *table, int flag)
{
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int delay_ms, ret = 0;
cmd_size = ext_config->cmd_size;
if (cmd_size < 2) {
EXTERR("%s: invalid cmd_size %d\n", __func__, cmd_size);
return -1;
}
if (flag)
max_len = ext_config->table_init_on_cnt;
else
max_len = ext_config->table_init_off_cnt;
while ((i + cmd_size) <= max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_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_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_GPIO) {
if (table[i+1] < LCD_GPIO_MAX)
lcd_extern_gpio_set(table[i+1], table[i+2]);
if (cmd_size > 3) {
if (table[i+3] > 0)
mdelay(table[i+3]);
}
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < (cmd_size - 1); j++)
delay_ms += table[i+1+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c_dev->client,
&table[i+1], (cmd_size-1));
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
if (i2c_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
ret = lcd_extern_i2c_write(i2c_dev->client,
&table[i+1], (cmd_size-2));
if (table[i+cmd_size-1] > 0)
mdelay(table[i+cmd_size-1]);
} else {
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, type);
}
i += cmd_size;
step++;
}
return ret;
@@ -116,15 +200,31 @@ static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
static int lcd_extern_power_ctrl(int flag)
{
unsigned char *table;
unsigned char cmd_size;
int ret = 0;
cmd_size = ext_config->cmd_size;
if (flag)
ret = lcd_extern_power_cmd(ext_config->table_init_on, 1);
table = ext_config->table_init_on;
else
ret = lcd_extern_power_cmd(ext_config->table_init_off, 0);
table = ext_config->table_init_off;
if (cmd_size < 1) {
EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
return -1;
}
if (table == NULL) {
EXTERR("%s: init_table %d is NULL\n", __func__, flag);
return -1;
}
EXTPR("%s(%d: %s): %d\n",
__func__, ext_config->index, ext_config->name, flag);
if (cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC)
ret = lcd_extern_power_cmd_dynamic_size(table, flag);
else
ret = lcd_extern_power_cmd_fixed_size(table, flag);
EXTPR("%s: %s(%d): %d\n",
__func__, ext_config->name, ext_config->index, flag);
return ret;
}
@@ -154,8 +254,11 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
}
if (ext_drv->config->table_init_loaded == 0) {
ext_drv->config->cmd_size = LCD_EXTERN_CMD_SIZE;
ext_drv->config->table_init_on = init_on_table;
ext_drv->config->table_init_on_cnt = sizeof(init_on_table);
ext_drv->config->table_init_off = init_off_table;
ext_drv->config->table_init_off_cnt = sizeof(init_off_table);
}
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;

View File

@@ -302,17 +302,15 @@ static int lcd_extern_power_off(void)
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
if (ext_drv == NULL) {
EXTERR("%s: driver is null\n", LCD_EXTERN_NAME);
return -1;
}
return ret;
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
return 0;
}
int aml_lcd_extern_i2c_anx6345_probe(struct aml_lcd_extern_driver_s *ext_drv)

View File

@@ -1,162 +0,0 @@
/*
* drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/amlogic/i2c-amlogic.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/of.h>
#include <linux/amlogic/media/vout/lcd/lcd_extern.h>
#include "lcd_extern.h"
#define LCD_EXTERN_NAME "i2c_tc101"
#define LCD_EXTERN_I2C_ADDR (0x7e) /* 7bit address */
#define LCD_EXTERN_I2C_ADDR2 (0xff) /* 7bit address */
#define LCD_EXTERN_I2C_BUS LCD_EXTERN_I2C_BUS_2
static struct lcd_extern_config_s *ext_config;
static struct aml_lcd_extern_i2c_dev_s *i2c0_dev;
static struct aml_lcd_extern_i2c_dev_s *i2c1_dev;
static unsigned char init_on_table[][3] = {
/* {0xff, 0xff, 20},//delay mark(20ms) */
{0xf8, 0x30, 0xb2},
{0xf8, 0x33, 0xc2},
{0xf8, 0x31, 0xf0},
{0xf8, 0x40, 0x80},
{0xf8, 0x81, 0xec},
{0xff, 0xff, 0xff},/* end mark */
};
static int lcd_extern_i2c_write(struct i2c_client *i2client,
unsigned char *buff, unsigned int len)
{
int ret = 0;
struct i2c_msg msg[] = {
{
.addr = i2client->addr,
.flags = 0,
.len = len,
.buf = buff,
}
};
ret = i2c_transfer(i2client->adapter, msg, 1);
if (ret < 0)
EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr);
return ret;
}
static int lcd_extern_power_on(void)
{
unsigned char tData[4];
int i = 0, ending_flag = 0;
int ret = 0;
lcd_extern_pinmux_set(1);
if (i2c0_dev == NULL) {
EXTERR("invalid i2c device\n");
return -1;
}
while (ending_flag == 0) {
if ((init_on_table[i][0] == 0xff) &&
(init_on_table[i][1] == 0xff)) { /* special mark */
if (init_on_table[i][2] == 0xff) /* ending flag */
ending_flag = 1;
else /* delay flag */
mdelay(init_on_table[i][2]);
} else {
tData[0] = init_on_table[i][0];
tData[1] = init_on_table[i][1];
tData[2] = init_on_table[i][2];
lcd_extern_i2c_write(i2c0_dev->client, tData, 3);
}
i++;
}
EXTPR("%s\n", __func__);
return ret;
}
static int lcd_extern_power_off(void)
{
int ret = 0;
lcd_extern_pinmux_set(0);
return ret;
}
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;
} else {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
}
return ret;
}
int aml_lcd_extern_i2c_tc101_probe(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
ext_config = ext_drv->config;
i2c0_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr);
if (i2c0_dev == NULL) {
EXTERR("invalid i2c0 device\n");
return -1;
}
EXTPR("get i2c0 device: %s, addr 0x%02x OK\n",
i2c0_dev->name, i2c0_dev->client->addr);
i2c1_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr2);
if (i2c1_dev == NULL) {
EXTERR("invalid i2c1 device\n");
i2c0_dev = NULL;
return -1;
}
EXTPR("get i2c1 device: %s, addr 0x%02x OK\n",
i2c1_dev->name, i2c1_dev->client->addr);
ret = lcd_extern_driver_update(ext_drv);
if (lcd_debug_print_flag)
EXTPR("%s: %d\n", __func__, ret);
return ret;
}
int aml_lcd_extern_i2c_tc101_remove(void)
{
i2c0_dev = NULL;
i2c1_dev = NULL;
ext_config = NULL;
return 0;
}

File diff suppressed because it is too large Load Diff

View File

@@ -55,6 +55,10 @@ extern int aml_lcd_extern_mipi_default_probe(
extern int aml_lcd_extern_i2c_T5800Q_probe(
struct aml_lcd_extern_driver_s *ext_drv);
#endif
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6862_7911
extern int aml_lcd_extern_i2c_ANX6862_7911_probe(
struct aml_lcd_extern_driver_s *ext_drv);
#endif
#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439
extern int aml_lcd_extern_i2c_DLPC3439_probe(
struct aml_lcd_extern_driver_s *ext_drv);

View File

@@ -103,17 +103,18 @@ static unsigned char mipi_init_off_table[] = {
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
return -1;
}
return ret;
ext_drv->config->cmd_size = LCD_EXT_CMD_SIZE_DYNAMIC;
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_on_cnt = sizeof(mipi_init_on_table);
ext_drv->config->table_init_off = &mipi_init_off_table[0];
ext_drv->config->table_init_off_cnt = sizeof(mipi_init_off_table);
return 0;
}
int aml_lcd_extern_mipi_KD080D13_probe(struct aml_lcd_extern_driver_s *ext_drv)

View File

@@ -220,17 +220,18 @@ static unsigned char mipi_init_off_table[] = {
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
return -1;
}
return ret;
ext_drv->config->cmd_size = LCD_EXT_CMD_SIZE_DYNAMIC;
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_on_cnt = sizeof(mipi_init_on_table);
ext_drv->config->table_init_off = &mipi_init_off_table[0];
ext_drv->config->table_init_off_cnt = sizeof(mipi_init_off_table);
return 0;
}
int aml_lcd_extern_mipi_N070ICN_probe(struct aml_lcd_extern_driver_s *ext_drv)

View File

@@ -209,17 +209,18 @@ static unsigned char mipi_init_off_table[] = {
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
return -1;
}
return ret;
ext_drv->config->cmd_size = LCD_EXT_CMD_SIZE_DYNAMIC;
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_on_cnt = sizeof(mipi_init_on_table);
ext_drv->config->table_init_off = &mipi_init_off_table[0];
ext_drv->config->table_init_off_cnt = sizeof(mipi_init_off_table);
return 0;
}
int aml_lcd_extern_mipi_p070acb_probe(struct aml_lcd_extern_driver_s *ext_drv)

View File

@@ -108,17 +108,18 @@ static unsigned char mipi_init_off_table[] = {
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
return -1;
}
return ret;
ext_drv->config->cmd_size = LCD_EXT_CMD_SIZE_DYNAMIC;
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_on_cnt = sizeof(mipi_init_on_table);
ext_drv->config->table_init_off = &mipi_init_off_table[0];
ext_drv->config->table_init_off_cnt = sizeof(mipi_init_off_table);
return 0;
}
int aml_lcd_extern_mipi_st7701_probe(struct aml_lcd_extern_driver_s *ext_drv)

View File

@@ -150,17 +150,18 @@ static unsigned char mipi_init_off_table[] = {
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
return -1;
}
return ret;
ext_drv->config->cmd_size = LCD_EXT_CMD_SIZE_DYNAMIC;
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_on_cnt = sizeof(mipi_init_on_table);
ext_drv->config->table_init_off = &mipi_init_off_table[0];
ext_drv->config->table_init_off_cnt = sizeof(mipi_init_off_table);
return 0;
}
int aml_lcd_extern_mipi_tl050fhv02ct_probe(

View File

@@ -171,17 +171,18 @@ static unsigned char mipi_init_off_table[] = {
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;
if (ext_drv) {
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_off = &mipi_init_off_table[0];
} else {
if (ext_drv == NULL) {
EXTERR("%s driver is null\n", LCD_EXTERN_NAME);
ret = -1;
return -1;
}
return ret;
ext_drv->config->cmd_size = LCD_EXT_CMD_SIZE_DYNAMIC;
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_on_cnt = sizeof(mipi_init_on_table);
ext_drv->config->table_init_off = &mipi_init_off_table[0];
ext_drv->config->table_init_off_cnt = sizeof(mipi_init_off_table);
return 0;
}
int aml_lcd_extern_mipi_TV070WSM_probe(struct aml_lcd_extern_driver_s *ext_drv)

View File

@@ -32,22 +32,30 @@
#define LCD_EXTERN_TYPE LCD_EXTERN_MIPI
/******************** mipi command ********************/
/**format: data_type, num, data**/
/*special: data_type=0xff, num<0xff means delay ms, num=0xff means ending.*/
/* format: data_type, cmd_size, data.... */
/* data_type=0xff,
* 0 < cmd_size < 0xff means delay ms,
* cmd_size=0 or 0xff means ending.
* data_type=0xf0, for gpio control
* data0=gpio_index, data1=gpio_value.
* data0=gpio_index, data1=gpio_value, data2=delay.
* data_type=0xfd, for delay ms
* data0=delay, data_1=delay, ..., data_n=delay.
*/
static unsigned char mipi_init_on_table[] = {
0x05, 1, 0x11,
0xff, 200,
0xfd, 1, 200,
0x05, 1, 0x29,
0xff, 20,
0xFF, 0xFF, /* ending flag */
0xfd, 1, 20,
0xff, 0, /* ending */
};
static unsigned char mipi_init_off_table[] = {
0x05, 1, 0x28, /* display off */
0xFF, 10, /* delay 10ms */
0xfd, 1, 10, /* delay 10ms */
0x05, 1, 0x10, /* sleep in */
0xFF, 150, /* delay 150ms */
0xFF, 0xFF, /* ending flag */
0xfd, 1, 150, /* delay 150ms */
0xff, 0, /* ending */
};
static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
@@ -57,26 +65,22 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
return -1;
}
if (ext_drv->config->type == LCD_EXTERN_MAX) { //default for no dt
ext_drv->config->index = LCD_EXTERN_INDEX;
ext_drv->config->type = LCD_EXTERN_TYPE;
strcpy(ext_drv->config->name, LCD_EXTERN_NAME);
ext_drv->config->table_init_on = &mipi_init_on_table[0];
if (ext_drv->config->table_init_loaded == 0) {
ext_drv->config->cmd_size = LCD_EXT_CMD_SIZE_DYNAMIC;
ext_drv->config->table_init_on = &mipi_init_on_table[0];
ext_drv->config->table_init_on_cnt =
sizeof(mipi_init_on_table);
ext_drv->config->table_init_off = &mipi_init_off_table[0];
ext_drv->config->table_init_off_cnt =
sizeof(mipi_init_off_table);
EXTERR("%s: tablet_init is invalid\n", ext_drv->config->name);
return -1;
}
return 0;
}
int aml_lcd_extern_mipi_default_get_default_index(void)
{
return LCD_EXTERN_INDEX;
}
int aml_lcd_extern_mipi_default_probe(
struct aml_lcd_extern_driver_s *ext_drv)
int aml_lcd_extern_mipi_default_probe(struct aml_lcd_extern_driver_s *ext_drv)
{
int ret = 0;

View File

@@ -40,28 +40,29 @@ static struct lcd_extern_config_s *ext_config;
#define SPI_GPIO_CS 0 /* index */
#define SPI_GPIO_CLK 1 /* index */
#define SPI_GPIO_DATA 2 /* index */
#define SPI_CLK_FREQ 10000 /* Hz */
#define SPI_CLK_FREQ 10 /* KHz */
#define SPI_CLK_POL 1
#define LCD_EXTERN_CMD_SIZE 4
#define LCD_EXTERN_CMD_SIZE 3
static unsigned char init_on_table[] = {
0x00, 0x00, 0x21, 0x00, /* reset */
0x00, 0x00, 0xa5, 0x00, /* standby */
0x00, 0x01, 0x30, 0x00, /* enable FRC/Dither */
0x00, 0x02, 0x40, 0x00, /* enable normally black */
0x00, 0x0e, 0x5f, 0x00, /* enable test mode1 */
0x00, 0x0f, 0xa4, 0x00, /* enable test mode2 */
0x00, 0x0d, 0x00, 0x00, /* enable SDRRS, enlarge OE width */
0x00, 0x02, 0x43, 0x00, /* adjust charge sharing time */
0x00, 0x0a, 0x28, 0x00, /* trigger bias reduction */
0x00, 0x10, 0x41, 50, /* adopt 2 line/1 dot */ /* delay 50ms */
0x00, 0x00, 0xad, 0x00, /* display on */
0xff, 0x00, 0x00, 0x00, /* ending flag */
0xc0, 0x00, 0x21, /* reset */
0xc0, 0x00, 0xa5, /* standby */
0xc0, 0x01, 0x30, /* enable FRC/Dither */
0xc0, 0x02, 0x40, /* enable normally black */
0xc0, 0x0e, 0x5f, /* enable test mode1 */
0xc0, 0x0f, 0xa4, /* enable test mode2 */
0xc0, 0x0d, 0x00, /* enable SDRRS, enlarge OE width */
0xc0, 0x02, 0x43, /* adjust charge sharing time */
0xc0, 0x0a, 0x28, /* trigger bias reduction */
0xc0, 0x10, 0x41, /* adopt 2 line/1 dot */ /* delay 50ms */
0xfd, 50, 0,
0xc0, 0x00, 0xad, /* display on */
0xff, 0x00, 0x00, /* ending */
};
static unsigned char init_off_table[] = {
0x00, 0x00, 0xa5, 0x00, /* standby */
0xff, 0x00, 0x00, 0x00, /* ending flag */
0xc0, 0x00, 0xa5, /* standby */
0xff, 0x00, 0x00, /* ending */
};
static void set_lcd_csb(unsigned int v)
@@ -96,7 +97,7 @@ static void spi_gpio_off(void)
set_lcd_csb(0);
}
static void spi_write_8(unsigned char addr, unsigned char data)
static void spi_write_byte(unsigned char addr, unsigned char data)
{
int i;
unsigned int sdata;
@@ -133,61 +134,128 @@ static int lcd_extern_spi_write(unsigned char *buf, int len)
EXTERR("%s: len %d error\n", __func__, len);
return -1;
}
spi_write_8(buf[0], buf[1]);
spi_write_byte(buf[0], buf[1]);
return 0;
}
static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
static int lcd_extern_power_cmd_dynamic_size(unsigned char *table, int flag)
{
int i = 0, max_len, step = 0;
unsigned char cmd_size;
int i = 0, j, step = 0, max_len = 0;
unsigned char type, cmd_size;
int delay_ms, ret = 0;
if (flag)
max_len = ext_config->table_init_on_cnt;
else
max_len = ext_config->table_init_off_cnt;
while ((i + 1) < max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (lcd_debug_print_flag) {
EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, type, table[i+1]);
}
cmd_size = table[i+1];
if (cmd_size == 0)
goto power_cmd_dynamic_next;
if ((i + 2 + cmd_size) > max_len)
break;
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (type == LCD_EXT_CMD_TYPE_GPIO) {
if (cmd_size < 2) {
EXTERR(
"step %d: invalid cmd_size %d for GPIO\n",
step, cmd_size);
goto power_cmd_dynamic_next;
}
if (table[i+2] < LCD_GPIO_MAX)
lcd_extern_gpio_set(table[i+2], table[i+3]);
if (cmd_size > 2) {
if (table[i+4] > 0)
mdelay(table[i+4]);
}
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += table[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = lcd_extern_spi_write(&table[i+2], cmd_size);
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = lcd_extern_spi_write(&table[i+2], (cmd_size-1));
if (table[i+cmd_size+1] > 0)
mdelay(table[i+cmd_size+1]);
} else {
EXTERR("%s: %s(%d): type 0x%02x invalid\n",
__func__, ext_config->name,
ext_config->index, type);
}
power_cmd_dynamic_next:
i += (cmd_size + 2);
step++;
}
return ret;
}
static int lcd_extern_power_cmd_fixed_size(unsigned char *table, int flag)
{
int i = 0, j, max_len, step = 0;
unsigned char type, cmd_size;
int ret = 0;
cmd_size = ext_config->cmd_size;
if (cmd_size < 1) {
if (cmd_size < 2) {
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;
}
if (flag)
max_len = LCD_EXTERN_INIT_ON_MAX;
max_len = ext_config->table_init_on_cnt;
else
max_len = LCD_EXTERN_INIT_OFF_MAX;
max_len = ext_config->table_init_off_cnt;
while (i <= max_len) {
if (init_table[i] == LCD_EXTERN_INIT_END)
while ((i + cmd_size) <= max_len) {
type = table[i];
if (type == LCD_EXT_CMD_TYPE_END)
break;
if (lcd_debug_print_flag) {
EXTPR("%s: step %d: type=0x%02x, cmd_size=%d\n",
__func__, step, init_table[i], cmd_size);
__func__, step, type, 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) {
lcd_extern_gpio_set(init_table[i+1],
init_table[i+2]);
if (type == LCD_EXT_CMD_TYPE_NONE) {
/* do nothing */
} else if (table[i] == LCD_EXT_CMD_TYPE_GPIO) {
if (table[i+1] < LCD_GPIO_MAX)
lcd_extern_gpio_set(table[i+1], table[i+2]);
if (cmd_size > 3) {
if (table[i+3] > 0)
mdelay(table[i+3]);
}
} else if (init_table[i] == LCD_EXTERN_INIT_CMD) {
ret = lcd_extern_spi_write(&init_table[i+1],
(cmd_size-2));
} else if (type == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < (cmd_size - 1); j++)
delay_ms += table[i+1+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (type == LCD_EXT_CMD_TYPE_CMD) {
ret = lcd_extern_spi_write(&table[i+1], (cmd_size-1));
} else if (type == LCD_EXT_CMD_TYPE_CMD_DELAY) {
ret = lcd_extern_spi_write(&table[i+1], (cmd_size-2));
if (table[i+cmd_size-1] > 0)
mdelay(table[i+cmd_size-1]);
} else {
EXTERR("%s(%d: %s): power_type %d is invalid\n",
EXTERR("%s(%d: %s): power_type 0x%02x is invalid\n",
__func__, ext_config->index,
ext_config->name, ext_config->type);
ext_config->name, type);
}
if (init_table[i+cmd_size-1] > 0)
mdelay(init_table[i+cmd_size-1]);
step++;
i += cmd_size;
step++;
}
return ret;
@@ -195,13 +263,31 @@ static int lcd_extern_power_cmd(unsigned char *init_table, int flag)
static int lcd_extern_power_ctrl(int flag)
{
unsigned char *table;
unsigned char cmd_size;
int ret = 0;
spi_gpio_init();
cmd_size = ext_config->cmd_size;
if (flag)
ret = lcd_extern_power_cmd(ext_config->table_init_on, 1);
table = ext_config->table_init_on;
else
ret = lcd_extern_power_cmd(ext_config->table_init_off, 0);
table = ext_config->table_init_off;
if (cmd_size < 1) {
EXTERR("%s: cmd_size %d is invalid\n", __func__, cmd_size);
return -1;
}
if (table == NULL) {
EXTERR("%s: init_table %d is NULL\n", __func__, flag);
return -1;
}
if (cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC)
ret = lcd_extern_power_cmd_dynamic_size(table, flag);
else
ret = lcd_extern_power_cmd_fixed_size(table, flag);
mdelay(10);
spi_gpio_off();
@@ -234,10 +320,13 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv)
}
if (ext_drv->config->table_init_loaded == 0) {
ext_drv->config->cmd_size = LCD_EXTERN_CMD_SIZE;
ext_drv->config->table_init_on = init_on_table;
ext_drv->config->table_init_on_cnt = sizeof(init_on_table);
ext_drv->config->table_init_off = init_off_table;
ext_drv->config->table_init_off_cnt = sizeof(init_off_table);
}
ext_drv->config->spi_delay_us = SPI_DELAY;
ext_drv->config->spi_delay_us = 1000 / ext_drv->config->spi_clk_freq;
ext_drv->power_on = lcd_extern_power_on;
ext_drv->power_off = lcd_extern_power_off;

View File

@@ -112,18 +112,24 @@ static void mipi_dsi_init_table_print(struct dsi_config_s *dconf, int on_off)
}
i = 0;
n = 0;
while ((i + 1) < n_max) {
if (dsi_table[i] == 0xff) { /* ctrl flag */
n = 0;
if (dsi_table[i+1] == 0xff) {
while ((i + DSI_CMD_SIZE_INDEX) < n_max) {
n = dsi_table[i+DSI_CMD_SIZE_INDEX];
if (dsi_table[i] == LCD_EXT_CMD_TYPE_END) {
if (n == 0xff) {
pr_info(" 0x%02x,0x%02x,\n",
dsi_table[i], dsi_table[i+1]);
break;
}
if (n == 0) {
pr_info(" 0x%02x,%d,\n",
dsi_table[i], dsi_table[i+1]);
break;
}
n = 0;
pr_info(" 0x%02x,%d,\n",
dsi_table[i], dsi_table[i+1]);
} else if (dsi_table[i] == 0xf0) { /* gpio */
n = dsi_table[i+DSI_CMD_SIZE_INDEX];
} else if ((dsi_table[i] == LCD_EXT_CMD_TYPE_GPIO) ||
(dsi_table[i] == LCD_EXT_CMD_TYPE_DELAY)) {
len = sprintf(str, " 0x%02x,%d,", dsi_table[i], n);
for (j = 0; j < n; j++) {
len += sprintf(str+len, "%d,",
@@ -135,7 +141,6 @@ static void mipi_dsi_init_table_print(struct dsi_config_s *dconf, int on_off)
on_off ? "on" : "off", dsi_table[i]);
break;
} else {
n = dsi_table[i+DSI_CMD_SIZE_INDEX];
len = sprintf(str, " 0x%02x,%d,", dsi_table[i], n);
for (j = 0; j < n; j++) {
len += sprintf(str+len, "0x%02x,",
@@ -272,9 +277,9 @@ int lcd_mipi_dsi_init_table_detect(struct device_node *m_node,
int ret = 0;
unsigned char *dsi_table;
unsigned char propname[15];
int i, j;
int n_max;
int i, j, n_max;
unsigned int *para; /* num 100 array */
unsigned char type, cmd_size;
unsigned int val;
if (on_off) {
@@ -302,63 +307,44 @@ int lcd_mipi_dsi_init_table_detect(struct device_node *m_node,
goto lcd_mipi_dsi_init_table_detect_err;
}
i = 0;
while ((i + 1) < n_max) {
while ((i + DSI_CMD_SIZE_INDEX) < n_max) {
ret = of_property_read_u32_index(m_node, propname, i, &val);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
if (val == 0xff) {
ret = of_property_read_u32_index(m_node,
propname, (i+1), &val);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
i += 2;
if (val == 0xff)
type = (unsigned char)val;
ret = of_property_read_u32_index(m_node, propname,
(i + DSI_CMD_SIZE_INDEX), &val);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
cmd_size = (unsigned char)val;
if (type == LCD_EXT_CMD_TYPE_END) {
if ((val == 0xff) || (val == 0))
break;
} else if (val == 0xf0) { /* cpu_gpio */
/* probe gpio */
cmd_size = 0;
}
if (cmd_size == 0) {
i += 2;
continue;
}
if ((i + 2 + cmd_size) > n_max) {
LCDERR("%s cmd_size out of support\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
if (type == LCD_EXT_CMD_TYPE_GPIO) {
/* probe gpio */
ret = of_property_read_u32_index(m_node,
propname, (i + DSI_GPIO_INDEX), &val);
propname, (i + 2), &val);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
lcd_cpu_gpio_probe(val);
/* cmd size */
ret = of_property_read_u32_index(m_node,
propname, (i + DSI_CMD_SIZE_INDEX), &val);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
if (val < 3) {
LCDERR("get %s wrong cmd_size %d for gpio\n",
propname, val);
break;
}
if ((i + 2 + val) >= n_max) {
LCDERR("get %s cmd_size out of max for gpio\n",
propname);
break;
}
i = i + (DSI_CMD_SIZE_INDEX + 1) + (val & 0xff);
} else if (val == 0xfc) { /* check state */
ret = of_property_read_u32_index(m_node,
propname, (i + DSI_CMD_SIZE_INDEX), &val);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
if ((i + 2 + val) >= n_max) {
LCDERR("get %s cmd_size out of max for check\n",
propname);
break;
}
} else if (type == LCD_EXT_CMD_TYPE_CHECK) {
ret = of_property_read_u32_index(m_node, propname,
(i + DSI_CMD_SIZE_INDEX + 1), &para[0]);
if (ret) {
@@ -375,35 +361,17 @@ int lcd_mipi_dsi_init_table_detect(struct device_node *m_node,
dconf->check_cnt = para[1];
if (dconf->check_cnt > 0)
dconf->check_en = 1;
i = i + (DSI_CMD_SIZE_INDEX + 1) + (val & 0xff);
} else if ((val & 0xf) == 0x0) {
LCDERR("get %s wrong data_type: 0x%02x\n",
propname, val);
break;
} else {
ret = of_property_read_u32_index(m_node,
propname, (i + DSI_CMD_SIZE_INDEX), &val);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
}
if ((i + 2 + val) >= n_max) {
LCDERR("get %s cmd_size out of max\n",
propname);
break;
}
i = i + (DSI_CMD_SIZE_INDEX + 1) + (val & 0xff);
}
i += (cmd_size + 2);
}
i = (i > n_max) ? n_max : i;
i += 2;
ret = of_property_read_u32_array(m_node, propname, &para[0], i);
if (ret) {
LCDERR("failed to get %s\n", propname);
goto lcd_mipi_dsi_init_table_detect_err;
} else {
for (j = 0; j < i; j++)
dsi_table[j] = (unsigned char)(para[j] & 0xff);
}
for (j = 0; j < i; j++)
dsi_table[j] = (unsigned char)(para[j] & 0xff);
if (lcd_debug_print_flag)
mipi_dsi_init_table_print(dconf, on_off);
@@ -1408,7 +1376,8 @@ mipi_dsi_check_state_err:
*/
int dsi_write_cmd(unsigned char *payload)
{
int i = 0, j = 0, num = 0;
int i = 0, j = 0, step = 0;
unsigned char cmd_size;
#ifdef DSI_CMD_READ_VALID
int k = 0, n = 0;
unsigned char rd_data[100];
@@ -1418,59 +1387,72 @@ int dsi_write_cmd(unsigned char *payload)
struct dsi_cmd_request_s dsi_cmd_req;
unsigned char vc_id = MIPI_DSI_VIRTUAL_CHAN_ID;
unsigned int req_ack = MIPI_DSI_DCS_ACK_TYPE;
int ret = 0;
int delay_ms, ret = 0;
/* mipi command(payload) */
/* format: data_type, cmd_size, data.... */
/* special: data_type=0xff,
/* data_type=0xff,
* cmd_size<0xff means delay ms,
* cmd_size=0xff means ending.
* data_type=0xf0,
* cmd_size=0xff or 0 means ending.
* data_type=0xf0, for gpio control
* data0=gpio_index, data1=gpio_value.
* data0=gpio_index, data1=gpio_value, data2=delay.
* data_type=0xfd, for delay ms
* data0=delay, data_1=delay, ..., data_n=delay.
*/
while (i < DSI_CMD_SIZE_MAX) {
while ((i + DSI_CMD_SIZE_INDEX) < DSI_CMD_SIZE_MAX) {
if (ret) {
LCDERR("%s: error, exit\n", __func__);
break;
}
if (payload[i] == 0xff) {
j = 2;
if (payload[i+1] == 0xff)
cmd_size = payload[i+DSI_CMD_SIZE_INDEX];
if (payload[i] == LCD_EXT_CMD_TYPE_END) {
if ((cmd_size == 0xff) || (cmd_size == 0))
break;
else
mdelay(payload[i+1]);
} else if (payload[i] == 0xf0) { /* gpio */
j = (DSI_CMD_SIZE_INDEX + 1) +
payload[i+DSI_CMD_SIZE_INDEX];
if (payload[i+DSI_CMD_SIZE_INDEX] < 3) {
LCDERR("wrong cmd_size %d for gpio\n",
payload[i+DSI_CMD_SIZE_INDEX]);
cmd_size = 0;
mdelay(payload[i+1]);
}
if (cmd_size == 0) {
i += (cmd_size + 2);
continue;
}
if (i + 2 + cmd_size > DSI_CMD_SIZE_MAX) {
LCDERR("step %d: cmd_size out of support\n", step);
break;
}
if (payload[i] == LCD_EXT_CMD_TYPE_DELAY) {
delay_ms = 0;
for (j = 0; j < cmd_size; j++)
delay_ms += payload[i+2+j];
if (delay_ms > 0)
mdelay(delay_ms);
} else if (payload[i] == LCD_EXT_CMD_TYPE_GPIO) {
if (cmd_size < 2) {
LCDERR(
"step %d: invalid cmd_size %d for gpio\n",
step, cmd_size);
break;
}
lcd_cpu_gpio_set(payload[i+DSI_GPIO_INDEX],
payload[i+DSI_GPIO_INDEX+1]);
if (payload[i+DSI_GPIO_INDEX+2])
mdelay(payload[i+DSI_GPIO_INDEX+2]);
} else if (payload[i] == 0xfc) { /* check state */
j = (DSI_CMD_SIZE_INDEX + 1) +
payload[i+DSI_CMD_SIZE_INDEX];
if (payload[i+DSI_CMD_SIZE_INDEX] < 2) {
LCDERR("wrong cmd_size %d for check state\n",
payload[i+DSI_CMD_SIZE_INDEX]);
lcd_cpu_gpio_set(payload[i+2], payload[i+3]);
if (cmd_size > 2) {
if (payload[i+4])
mdelay(payload[i+4]);
}
} else if (payload[i] == LCD_EXT_CMD_TYPE_CHECK) {
if (cmd_size < 2) {
LCDERR(
"step %d: invalid cmd_size %d for check state\n",
step, cmd_size);
break;
}
if (payload[i+DSI_GPIO_INDEX+2] > 0) {
ret = mipi_dsi_check_state(
payload[i+DSI_GPIO_INDEX],
payload[i+DSI_GPIO_INDEX+1]);
if (payload[i+3] > 0) {
ret = mipi_dsi_check_state(payload[i+2],
payload[i+3]);
}
} else if ((payload[i] & 0xf) == 0x0) {
LCDERR("data_type: 0x%02x\n", payload[i]);
break;
} else {
/* payload[i+DSI_CMD_SIZE_INDEX] is data count */
j = (DSI_CMD_SIZE_INDEX + 1) +
payload[i+DSI_CMD_SIZE_INDEX];
dsi_cmd_req.data_type = payload[i];
dsi_cmd_req.vc_id = (vc_id & 0x3);
dsi_cmd_req.payload = &payload[i];
@@ -1544,17 +1526,18 @@ int dsi_write_cmd(unsigned char *payload)
break;
#endif
default:
LCDPR("[warning]un-support data_type: 0x%02x\n",
dsi_cmd_req.data_type);
LCDPR(
"[warning]: step %d: un-support data_type: 0x%02x\n",
step, dsi_cmd_req.data_type);
break;
}
}
i += j;
num++;
i += (cmd_size + 2);
step++;
}
return num;
return step;
}
static void mipi_dsi_phy_config(struct dsi_phy_s *dphy, unsigned int dsi_ui)

View File

@@ -17,6 +17,7 @@
#ifndef _INC_AML_BL_EXTERN_H_
#define _INC_AML_BL_EXTERN_H_
#include <linux/amlogic/media/vout/lcd/aml_lcd.h>
enum bl_extern_type_e {
BL_EXTERN_I2C = 0,
@@ -25,29 +26,12 @@ enum bl_extern_type_e {
BL_EXTERN_MAX,
};
enum bl_extern_i2c_bus_e {
BL_EXTERN_I2C_BUS_0 = 0,
BL_EXTERN_I2C_BUS_1,
BL_EXTERN_I2C_BUS_2,
BL_EXTERN_I2C_BUS_3,
BL_EXTERN_I2C_BUS_4,
BL_EXTERN_I2C_BUS_MAX,
};
#define BL_EXTERN_I2C_BUS_INVALID 0xff
#define BL_EXTERN_INIT_ON_MAX 300
#define BL_EXTERN_INIT_OFF_MAX 50
#define BL_EXTERN_SPI_CLK_FREQ_DFT 10000 /* default 10k */
#define BL_EXTERN_INIT_TABLE_MAX 500
#define BL_EXTERN_INIT_CMD 0x00
#define BL_EXTERN_INIT_NONE 0xf0
#define BL_EXTERN_INIT_END 0xff
#define BL_EXTERN_DYNAMIC_LEN 0xff
#define BL_EXTERN_GPIO_NUM_MAX 6
#define BL_EXTERN_INDEX_INVALID 0xff
#define BL_EXTERN_NAME_LEN_MAX 30
#define BL_EXTERN_GPIO_NUM_MAX 6
#define BL_EXTERN_INDEX_INVALID 0xff
#define BL_EXTERN_NAME_LEN_MAX 30
struct bl_extern_config_s {
unsigned char index;
char name[BL_EXTERN_NAME_LEN_MAX];
@@ -56,6 +40,13 @@ struct bl_extern_config_s {
unsigned char i2c_bus;
unsigned int dim_min;
unsigned int dim_max;
unsigned char init_loaded;
unsigned char cmd_size;
unsigned char *init_on;
unsigned char *init_off;
unsigned int init_on_cnt;
unsigned int init_off_cnt;
};
/* global API */

View File

@@ -0,0 +1,53 @@
/*
* include/linux/amlogic/media/vout/lcd/aml_lcd.h
*
* Copyright (C) 2017 Amlogic, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
*/
#ifndef _INC_AML_LCD_COMMON_H_
#define _INC_AML_LCD_COMMON_H_
#define LCD_EXT_I2C_BUS_0 0 /* A */
#define LCD_EXT_I2C_BUS_1 1 /* B */
#define LCD_EXT_I2C_BUS_2 2 /* C */
#define LCD_EXT_I2C_BUS_3 3 /* D */
#define LCD_EXT_I2C_BUS_4 4 /* AO */
#define LCD_EXT_I2C_BUS_MAX 0xff
#define LCD_EXT_I2C_BUS_INVALID 0xff
#define LCD_EXT_I2C_ADDR_INVALID 0xff
#define LCD_EXT_GPIO_INVALID 0xff
#define LCD_EXT_SPI_CLK_FREQ_DFT 10 /* unit: KHz */
/*******************************************/
/* LCD EXT CMD */
/*******************************************/
#define LCD_EXT_CMD_TYPE_CMD_DELAY 0x00
#define LCD_EXT_CMD_TYPE_CMD2_DELAY 0x01 /* for i2c device 2nd addr */
#define LCD_EXT_CMD_TYPE_NONE 0x10
#define LCD_EXT_CMD_TYPE_CMD 0xc0
#define LCD_EXT_CMD_TYPE_CMD2 0xc1 /* for i2c device 2nd addr */
#define LCD_EXT_CMD_TYPE_GPIO 0xf0
#define LCD_EXT_CMD_TYPE_CHECK 0xfc
#define LCD_EXT_CMD_TYPE_DELAY 0xfd
#define LCD_EXT_CMD_TYPE_END 0xff
#define LCD_EXT_CMD_SIZE_DYNAMIC 0xff
#define LCD_EXT_DYNAMIC_SIZE_INDEX 1
#endif

View File

@@ -22,6 +22,7 @@
#include <linux/amlogic/aml_gpio_consumer.h>
#include <linux/pinctrl/consumer.h>
#include <linux/amlogic/media/vout/lcd/aml_bl.h>
#include <linux/amlogic/media/vout/lcd/aml_lcd.h>
#include <linux/spi/spi.h>
/*#define LDIM_DEBUG_INFO*/
@@ -75,8 +76,8 @@ struct ldim_config_s {
unsigned char bl_mode;
};
#define LDIM_SPI_INIT_ON_SIZE 300
#define LDIM_SPI_INIT_OFF_SIZE 20
#define LDIM_INIT_ON_MAX 300
#define LDIM_INIT_OFF_MAX 20
struct ldim_dev_config_s {
char name[20];
char pinmux_name[20];
@@ -92,9 +93,13 @@ struct ldim_dev_config_s {
unsigned int dim_min;
unsigned int dim_max;
unsigned char init_loaded;
unsigned char cmd_size;
unsigned char *init_on;
unsigned char *init_off;
unsigned int init_on_cnt;
unsigned int init_off_cnt;
struct bl_pwm_config_s pwm_config;

View File

@@ -17,6 +17,7 @@
#ifndef _INC_AML_LCD_EXTERN_H_
#define _INC_AML_LCD_EXTERN_H_
#include <linux/amlogic/media/vout/lcd/aml_lcd.h>
enum lcd_extern_type_e {
LCD_EXTERN_I2C = 0,
@@ -25,29 +26,9 @@ enum lcd_extern_type_e {
LCD_EXTERN_MAX,
};
#define LCD_EXTERN_I2C_BUS_0 0
#define LCD_EXTERN_I2C_BUS_1 1
#define LCD_EXTERN_I2C_BUS_2 2
#define LCD_EXTERN_I2C_BUS_3 3
#define LCD_EXTERN_I2C_BUS_4 4
#define LCD_EXTERN_I2C_BUS_MAX 0xff
#define LCD_EXTERN_I2C_BUS_INVALID 0xff
#define LCD_EXTERN_I2C_ADDR_INVALID 0xff
#define LCD_EXTERN_SPI_CLK_FREQ_DFT 10000 /* default 10k */
#define LCD_EXTERN_INIT_ON_MAX 3000
#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_NONE 0x10
#define LCD_EXTERN_INIT_GPIO 0xf0
#define LCD_EXTERN_INIT_END 0xff
#define LCD_EXTERN_CMD_SIZE_DYNAMIC 0xff
#define LCD_EXTERN_DYNAMIC_SIZE_INDEX 1
#define LCD_EXTERN_GPIO_NUM_MAX 6
#define LCD_EXTERN_INDEX_INVALID 0xff
@@ -71,15 +52,16 @@ struct lcd_extern_config_s {
unsigned char spi_gpio_cs;
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 short spi_clk_freq; /*KHz */
unsigned short spi_delay_us;
unsigned char cmd_size;
unsigned char table_init_loaded; /* internal use */
unsigned int table_init_on_cnt;
unsigned int table_init_off_cnt;
unsigned char *table_init_on;
unsigned char *table_init_off;
unsigned char table_init_loaded; /* internal use */
unsigned int table_init_on_cnt; /* internal use */
};
/* global API */