From 783b7b4e7da19f190a072b271e1574f38eacf14e Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Tue, 4 Sep 2018 13:34:38 +0800 Subject: [PATCH] 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 --- MAINTAINERS | 6 +- arch/arm/boot/dts/amlogic/mesontxl_p321-panel.dtsi | 38 +- .../arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi | 132 ++- arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts | 14 + arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts | 14 + arch/arm/configs/meson64_a32_defconfig | 1 + arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts | 15 +- .../boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts | 16 +- arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts | 14 + .../boot/dts/amlogic/mesonaxg_s400-panel.dtsi | 96 +- .../boot/dts/amlogic/mesong12a_skt-panel.dtsi | 136 ++- .../boot/dts/amlogic/mesong12b_skt-panel.dtsi | 74 +- .../boot/dts/amlogic/mesongxl_p212-panel.dtsi | 40 +- .../boot/dts/amlogic/mesongxm_q200-panel.dtsi | 40 +- .../boot/dts/amlogic/mesontxl_p321-panel.dtsi | 40 +- .../boot/dts/amlogic/mesontxlx_r311-panel.dtsi | 132 ++- arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts | 14 + arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts | 14 + .../boot/dts/amlogic/txlx_t962x_r311_720p.dts | 14 + arch/arm64/configs/meson64_defconfig | 1 + .../media/vout/backlight/aml_ldim/iw7027_bl.c | 134 ++- .../media/vout/backlight/aml_ldim/ldim_dev_drv.c | 511 +++++++-- .../media/vout/backlight/bl_extern/bl_extern.c | 519 ++++++++- .../media/vout/backlight/bl_extern/bl_extern.dts | 2 +- .../media/vout/backlight/bl_extern/bl_extern.h | 9 +- .../media/vout/backlight/bl_extern/bl_extern_i2c.c | 1 + .../media/vout/backlight/bl_extern/i2c_lp8556.c | 166 ++- .../vout/backlight/bl_extern/mipi_lt070me05.c | 13 +- drivers/amlogic/media/vout/lcd/lcd_common.c | 2 + drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig | 18 +- drivers/amlogic/media/vout/lcd/lcd_extern/Makefile | 1 + .../media/vout/lcd/lcd_extern/ext_default.c | 315 +++--- .../media/vout/lcd/lcd_extern/i2c_ANX6862_7911.c | 523 +++++++++ .../media/vout/lcd/lcd_extern/i2c_DLPC3439.c | 12 +- .../amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c | 197 +++- .../media/vout/lcd/lcd_extern/i2c_anx6345.c | 16 +- .../amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c | 162 --- .../amlogic/media/vout/lcd/lcd_extern/lcd_extern.c | 1184 +++++++++++--------- .../amlogic/media/vout/lcd/lcd_extern/lcd_extern.h | 4 + .../media/vout/lcd/lcd_extern/mipi_KD080D13.c | 17 +- .../media/vout/lcd/lcd_extern/mipi_N070ICN.c | 17 +- .../media/vout/lcd/lcd_extern/mipi_P070ACB.c | 17 +- .../media/vout/lcd/lcd_extern/mipi_ST7701.c | 17 +- .../media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c | 17 +- .../media/vout/lcd/lcd_extern/mipi_TV070WSM.c | 17 +- .../media/vout/lcd/lcd_extern/mipi_default.c | 48 +- .../media/vout/lcd/lcd_extern/spi_LD070WS2.c | 193 +++- .../media/vout/lcd/lcd_tablet/mipi_dsi_util.c | 217 ++-- .../linux/amlogic/media/vout/lcd/aml_bl_extern.h | 35 +- include/linux/amlogic/media/vout/lcd/aml_lcd.h | 53 + include/linux/amlogic/media/vout/lcd/aml_ldim.h | 9 +- include/linux/amlogic/media/vout/lcd/lcd_extern.h | 30 +- 52 files changed, 3584 insertions(+), 1743 deletions(-) create mode 100644 drivers/amlogic/media/vout/lcd/lcd_extern/i2c_ANX6862_7911.c delete mode 100644 drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c create mode 100644 include/linux/amlogic/media/vout/lcd/aml_lcd.h diff --git a/MAINTAINERS b/MAINTAINERS index 179435a..f0587b3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -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 F: include/dt-bindings/clock/amlogic,tl1-clkc.h F: drivers/amlogic/clk/tl1/* - diff --git a/arch/arm/boot/dts/amlogic/mesontxl_p321-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontxl_p321-panel.dtsi index f3f1ba2..44c2389 100644 --- a/arch/arm/boot/dts/amlogic/mesontxl_p321-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontxl_p321-panel.dtsi @@ -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", diff --git a/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi b/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi index 2df7e9c..caf0f3f 100644 --- a/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi +++ b/arch/arm/boot/dts/amlogic/mesontxlx_r311-panel.dtsi @@ -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>; }; }; diff --git a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts index b9b6bfe..bf34895 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_1g.dts @@ -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 { diff --git a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts index 9a39e56..f9f5c0e 100644 --- a/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -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 { diff --git a/arch/arm/configs/meson64_a32_defconfig b/arch/arm/configs/meson64_a32_defconfig index 99df026..94f70a6 100644 --- a/arch/arm/configs/meson64_a32_defconfig +++ b/arch/arm/configs/meson64_a32_defconfig @@ -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 diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts index 3a7ca54..ccf02f0 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts @@ -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"; }; }; diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts index eaa3bd3..dd942ba 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts @@ -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"; }; }; diff --git a/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts b/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts index 2385a90..6d9d5f1 100644 --- a/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12b_a311d_skt.dts @@ -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 { diff --git a/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi index 67d0c0a..a11f723 100644 --- a/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi @@ -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"; diff --git a/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi index 9ee5bcb3..9970eeb 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi @@ -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"; diff --git a/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi index 7182b40..97e0597 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi @@ -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"; diff --git a/arch/arm64/boot/dts/amlogic/mesongxl_p212-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesongxl_p212-panel.dtsi index 5df7e23..db3b994 100644 --- a/arch/arm64/boot/dts/amlogic/mesongxl_p212-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesongxl_p212-panel.dtsi @@ -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 */ diff --git a/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi index 6627036..1494b0f 100644 --- a/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi @@ -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 */ diff --git a/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi index 4d062ce..2272023 100644 --- a/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontxl_p321-panel.dtsi @@ -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", diff --git a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi index e37e864..973142ac 100644 --- a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi @@ -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>; }; }; diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts index 017e54b..0c6eaf0 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts @@ -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 { diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts index fb3aaac..dbb77ec 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -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 { diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts index 43419ff..248d2ee 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts @@ -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 { diff --git a/arch/arm64/configs/meson64_defconfig b/arch/arm64/configs/meson64_defconfig index 968ee40..918e92d 100644 --- a/arch/arm64/configs/meson64_defconfig +++ b/arch/arm64/configs/meson64_defconfig @@ -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 diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c index 2878280..1085fcd 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/iw7027_bl.c @@ -25,20 +25,16 @@ #include #include #include -#include #include #include #include #include #include -#include #include #include #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); diff --git a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c index e7a0456..fe274ac 100644 --- a/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c +++ b/drivers/amlogic/media/vout/backlight/aml_ldim/ldim_dev_drv.c @@ -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; - } - 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_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; + ldim_dev_config.cmd_size = (unsigned char)val; + } + 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 == 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); diff --git a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.c b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.c index 6065410..bdbacf4 100644 --- a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.c +++ b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.c @@ -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: + 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("index: %d\n" - "name: %s\n" - "type: mipi(%d)\n" + 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; diff --git a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.dts b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.dts index 58cad99..e002d11 100644 --- a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.dts +++ b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.dts @@ -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>; }; diff --git a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.h b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.h index 29ca493..902c00c 100644 --- a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.h +++ b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern.h @@ -17,11 +17,9 @@ #ifndef _BL_EXTERN_H_ #define _BL_EXTERN_H_ -#include #include -#include -#include -#include +#include + 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); diff --git a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern_i2c.c b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern_i2c.c index a312537..2eb1233 100644 --- a/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern_i2c.c +++ b/drivers/amlogic/media/vout/backlight/bl_extern/bl_extern_i2c.c @@ -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; diff --git a/drivers/amlogic/media/vout/backlight/bl_extern/i2c_lp8556.c b/drivers/amlogic/media/vout/backlight/bl_extern/i2c_lp8556.c index c62c0f2..8a670fd 100644 --- a/drivers/amlogic/media/vout/backlight/bl_extern/i2c_lp8556.c +++ b/drivers/amlogic/media/vout/backlight/bl_extern/i2c_lp8556.c @@ -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; + while ((i + 1) < 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, 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 = 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++; } - if (i2c_dev == NULL) { - BLEXERR("invalid i2c device\n"); + + 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; } - len = BL_EXTERN_CMD_SIZE; - while (i <= BL_EXTERN_INIT_TABLE_MAX) { - if (init_table[i] == BL_EXTERN_INIT_END) { + 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; - } else if (init_table[i] == BL_EXTERN_INIT_NONE) { - /* do nothing, only for delay */ - } else if (init_table[i] == BL_EXTERN_INIT_CMD) { + 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, - &init_table[i+1], (len-2)); + &table[i+1], (cmd_size-2)); + if (table[i+cmd_size-1] > 0) + mdelay(table[i+cmd_size-1]); } else { - BLEXERR("%s: %s(%d): power_type %d is invalid\n", + BLEXERR("%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+len-1] > 0) - mdelay(init_table[i+len-1]); - i += len; + 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; } diff --git a/drivers/amlogic/media/vout/backlight/bl_extern/mipi_lt070me05.c b/drivers/amlogic/media/vout/backlight/bl_extern/mipi_lt070me05.c index 1dce058..3265c6a 100644 --- a/drivers/amlogic/media/vout/backlight/bl_extern/mipi_lt070me05.c +++ b/drivers/amlogic/media/vout/backlight/bl_extern/mipi_lt070me05.c @@ -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) { diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.c b/drivers/amlogic/media/vout/lcd/lcd_common.c index 3f32095..4e94f18 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.c +++ b/drivers/amlogic/media/vout/lcd/lcd_common.c @@ -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) { diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig b/drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig index 7c22f7a..b346b01 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/Kconfig @@ -15,32 +15,32 @@ config AMLOGIC_LCD_EXTERN_I2C_T5800Q 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" +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_DLPC3439 init driver support + 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_ANX6345 - bool "lcd external i2c ANX6345 init driver" +config AMLOGIC_LCD_EXTERN_I2C_DLPC3439 + bool "lcd external i2c DLPC3439 init driver" default n depends on AMLOGIC_LCD_EXTERN help - Amlogic LCD external i2c_ANX6345 init driver support + Amlogic LCD external i2c_DLPC3439 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_TC101 - bool "lcd external i2c TC101 init driver" +config AMLOGIC_LCD_EXTERN_I2C_ANX6345 + bool "lcd external i2c ANX6345 init driver" default n depends on AMLOGIC_LCD_EXTERN help - Amlogic LCD external i2c_TC101 init driver support + Amlogic LCD external i2c_ANX6345 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 diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile b/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile index fed2ce1..376ffd6 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile @@ -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 diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c b/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c index ee25a68..b0e76ba 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c @@ -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]); + } + } 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, + &table[i+2], cmd_size); + } else if (type == LCD_EXT_CMD_TYPE_CMD2) { + if (i2c1_dev == NULL) { + EXTERR("invalid i2c1 device\n"); + return -1; } - if (init_table[i+4] > 0) - mdelay(init_table[i+4]); - } else if (type == LCD_EXTERN_INIT_CMD) { + ret = lcd_extern_i2c_write(i2c1_dev->client, + &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, - &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-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, - &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-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; + 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 = 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; - cmd_size = ext_config->cmd_size; 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]); + } + 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, + &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; } - } else if (type == LCD_EXTERN_INIT_CMD) { + ret = lcd_extern_i2c_write(i2c1_dev->client, + &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, - &init_table[i+1], (cmd_size-2)); - } else if (type == LCD_EXTERN_INIT_CMD2) { + &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, - &init_table[i+1], (cmd_size-2)); + &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]); + } + if (cmd_size > 3) { + if (table[i+3] > 0) + mdelay(table[i+3]); } - } else if (type == LCD_EXTERN_INIT_CMD) { - ret = lcd_extern_spi_write(&init_table[i+1], + } 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(); + cmd_size = ext_config->cmd_size; if (flag) - init_table = ext_config->table_init_on; + table = ext_config->table_init_on; else - init_table = ext_config->table_init_off; - cmd_size = ext_config->cmd_size; + 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) { diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_ANX6862_7911.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_ANX6862_7911.c new file mode 100644 index 0000000..2d3a70b --- /dev/null +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_ANX6862_7911.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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; +} + diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c index 0f0281e..ad5f746 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c @@ -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; } diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c index 9f86fe7..49cf9dc 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c @@ -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; + 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 < 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 (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) { + if (i2c_dev == NULL) { + EXTERR("invalid i2c device\n"); + return -1; + } + ret = lcd_extern_i2c_write(i2c_dev->client, + &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: %s(%d): type 0x%02x invalid\n", + __func__, ext_config->name, + ext_config->index, type); + } +power_cmd_dynamic_next: + i += (cmd_size + 2); + step++; } - if (init_table == NULL) { - EXTERR("%s: init_table %d is NULL\n", __func__, flag); + + 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 = 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) + 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 (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 (init_table[i] == LCD_EXTERN_INIT_CMD) { + } 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, - &init_table[i+1], (cmd_size-2)); + &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(%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]); - step++; 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 + 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(ext_config->table_init_off, 0); + ret = lcd_extern_power_cmd_fixed_size(table, flag); - EXTPR("%s(%d: %s): %d\n", - __func__, ext_config->index, ext_config->name, 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; diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c index 64e1f0c3..d183d8b 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c @@ -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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c deleted file mode 100644 index af8d3a5..0000000 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c +++ /dev/null @@ -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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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; -} diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c b/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c index 3f0b5ec..f84a616 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c @@ -32,9 +32,10 @@ static struct device *lcd_extern_dev; static struct aml_lcd_extern_driver_s *lcd_ext_driver; -static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf); static unsigned char lcd_ext_config_load; +static unsigned char *table_init_on_dft; +static unsigned char *table_init_off_dft; struct lcd_ext_gpio_s { char name[15]; @@ -62,24 +63,25 @@ static struct lcd_extern_config_s lcd_extern_config = { .key_valid = 0, .addr_sel = 0, - .i2c_addr = LCD_EXTERN_I2C_ADDR_INVALID, - .i2c_addr2 = LCD_EXTERN_I2C_ADDR_INVALID, - .i2c_bus = LCD_EXTERN_I2C_BUS_INVALID, - .i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX, - .i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX, + .i2c_addr = LCD_EXT_I2C_ADDR_INVALID, + .i2c_addr2 = LCD_EXT_I2C_ADDR_INVALID, + .i2c_bus = LCD_EXT_I2C_BUS_INVALID, + .i2c_sck_gpio = LCD_EXT_GPIO_INVALID, + .i2c_sda_gpio = LCD_EXT_GPIO_INVALID, - .spi_gpio_cs = LCD_EXTERN_GPIO_NUM_MAX, - .spi_gpio_clk = LCD_EXTERN_GPIO_NUM_MAX, - .spi_gpio_data = LCD_EXTERN_GPIO_NUM_MAX, + .spi_gpio_cs = LCD_EXT_GPIO_INVALID, + .spi_gpio_clk = LCD_EXT_GPIO_INVALID, + .spi_gpio_data = LCD_EXT_GPIO_INVALID, .spi_clk_freq = 0, .spi_delay_us = 0, .spi_clk_pol = 1, .cmd_size = 0, + .table_init_loaded = 0, /* internal use */ + .table_init_on_cnt = 0, + .table_init_off_cnt = 0, .table_init_on = NULL, .table_init_off = NULL, - .table_init_loaded = 0, /* internal use */ - .table_init_on_cnt = 0, /* internal use */ }; struct aml_lcd_extern_driver_s *aml_lcd_extern_get_driver(int index) @@ -346,27 +348,27 @@ static unsigned char lcd_extern_get_i2c_bus_str(const char *str) unsigned char i2c_bus; if (strncmp(str, "i2c_bus_ao", 10) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_4; + i2c_bus = LCD_EXT_I2C_BUS_4; else if (strncmp(str, "i2c_bus_a", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_0; + i2c_bus = LCD_EXT_I2C_BUS_0; else if (strncmp(str, "i2c_bus_b", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_1; + i2c_bus = LCD_EXT_I2C_BUS_1; else if (strncmp(str, "i2c_bus_c", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_2; + i2c_bus = LCD_EXT_I2C_BUS_2; else if (strncmp(str, "i2c_bus_d", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_3; + i2c_bus = LCD_EXT_I2C_BUS_3; else if (strncmp(str, "i2c_bus_0", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_0; + i2c_bus = LCD_EXT_I2C_BUS_0; else if (strncmp(str, "i2c_bus_1", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_1; + i2c_bus = LCD_EXT_I2C_BUS_1; else if (strncmp(str, "i2c_bus_2", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_2; + i2c_bus = LCD_EXT_I2C_BUS_2; else if (strncmp(str, "i2c_bus_3", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_3; + i2c_bus = LCD_EXT_I2C_BUS_3; else if (strncmp(str, "i2c_bus_4", 9) == 0) - i2c_bus = LCD_EXTERN_I2C_BUS_4; + i2c_bus = LCD_EXT_I2C_BUS_4; else { - i2c_bus = LCD_EXTERN_I2C_BUS_INVALID; + i2c_bus = LCD_EXT_I2C_BUS_INVALID; EXTERR("invalid i2c_bus: %s\n", str); } @@ -388,186 +390,167 @@ static int lcd_extern_init_table_dynamic_size_load_dts( struct lcd_extern_config_s *extconf, int flag) { unsigned char cmd_size, index, type; - int i, j, val, max_len, step = 0, ret = 0; - unsigned char *init_table; + int i = 0, j, val, max_len, step = 0, ret = 0; + unsigned char *table; char propname[20]; if (flag) { - init_table = extconf->table_init_on; + table = table_init_on_dft; max_len = LCD_EXTERN_INIT_ON_MAX; sprintf(propname, "init_on"); } else { - init_table = extconf->table_init_off; + table = table_init_off_dft; max_len = LCD_EXTERN_INIT_OFF_MAX; sprintf(propname, "init_off"); } + if (table == NULL) { + EXTERR("%s: init_table is null\n", __func__); + return -1; + } switch (extconf->type) { case LCD_EXTERN_I2C: case LCD_EXTERN_SPI: - i = 0; - while ((i + 1) < max_len) { /* type & cmd_size detect */ - /* step1: type */ + while ((i + 1) < max_len) { + /* type */ ret = of_property_read_u32_index( of_node, propname, i, &val); if (ret) { - EXTERR("get %s %s type failed, step %d\n", + EXTERR("%s: get %s type failed, step %d\n", extconf->name, propname, step); - init_table[i] = LCD_EXTERN_INIT_END; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } - init_table[i] = (unsigned char)val; - type = init_table[i]; - if (type == LCD_EXTERN_INIT_END) - break; - /* step2: cmd_size */ + table[i] = (unsigned char)val; + type = table[i]; + /* cmd_size */ ret = of_property_read_u32_index( of_node, propname, (i+1), &val); if (ret) { - EXTERR("get %s %s cmd_size failed, step %d\n", + EXTERR("%s: get %s cmd_size failed, step %d\n", extconf->name, propname, step); - init_table[i] = LCD_EXTERN_INIT_END; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } - init_table[i+1] = (unsigned char)val; - cmd_size = init_table[i+1]; - if (cmd_size == 0) { - i += 2; - continue; - } + 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_i2c_spi_dts_next; if ((i + 2 + cmd_size) > max_len) { - EXTERR("%s %s cmd_size out of max, step %d\n", + EXTERR( + "%s: %s cmd_size out of support, step %d\n", extconf->name, propname, step); - init_table[i] = LCD_EXTERN_INIT_END; - init_table[i+1] = 0; - break; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; + return -1; } - /* step3: data */ + + /* data */ for (j = 0; j < cmd_size; j++) { ret = of_property_read_u32_index( of_node, propname, (i+2+j), &val); if (ret) { - EXTERR("get %s%s data failed,step%d\n", + EXTERR( + "%s: get %s data failed, step %d\n", extconf->name, propname, step); - init_table[i] = LCD_EXTERN_INIT_END; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } - init_table[i+2+j] = (unsigned char)val; + table[i+2+j] = (unsigned char)val; } - if (type == LCD_EXTERN_INIT_GPIO) { + if (type == LCD_EXT_CMD_TYPE_GPIO) { /* gpio probe */ - index = init_table[i+2]; + index = table[i+2]; if (index < LCD_EXTERN_GPIO_NUM_MAX) lcd_extern_gpio_probe(index); } - step++; + +init_table_dynamic_i2c_spi_dts_next: i += (cmd_size + 2); + step++; } + if (flag) + extconf->table_init_on_cnt = i + 2; + else + extconf->table_init_off_cnt = i + 2; break; case LCD_EXTERN_MIPI: - i = 0; - while ((i + 1) < max_len) { /* type & cmd_size detect */ + while ((i + 1) < max_len) { + /* type */ ret = of_property_read_u32_index( of_node, propname, i, &val); if (ret) { - EXTERR("get %s %s type failed\n", - extconf->name, propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; + EXTERR("%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; } - init_table[i] = (unsigned char)val; - type = (unsigned char)val; - if (type == 0xff) { - ret = of_property_read_u32_index( - of_node, propname, (i+1), &val); - if (ret) { - EXTERR("get %s %s cmd_size failed\n", - extconf->name, propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - init_table[i+1] = (unsigned char)val; - cmd_size = init_table[i+1]; - if (cmd_size == 0xff) + table[i] = (unsigned char)val; + type = table[i]; + /* cmd_size */ + ret = of_property_read_u32_index( + of_node, propname, (i+1), &val); + if (ret) { + EXTERR("%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) { + if ((cmd_size == 0xff) || (cmd_size == 0)) break; - i += 2; - } else if (type == 0xf0) { + cmd_size = 0; + } + if (cmd_size == 0) + goto init_table_dynamic_mipi_dts_next; + if ((i + 2 + cmd_size) > max_len) { + EXTERR( + "%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; + } + + for (j = 0; j < cmd_size; j++) { ret = of_property_read_u32_index( - of_node, propname, (i+1), &val); + of_node, propname, (i+2+j), &val); if (ret) { - EXTERR("get %s %s type failed\n", - extconf->name, propname); - init_table[i+1] = 0xff; + EXTERR("%s: get %s 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; + } + + if (type == LCD_EXT_CMD_TYPE_GPIO) { /* gpio probe */ - init_table[i+1] = val; - cmd_size = val; - if (cmd_size < 3) { - EXTERR("%s %s invalid cmd_size gpio\n", - extconf->name, propname); - return -1; - } - if ((i + 2 + cmd_size) >= max_len) { - EXTERR("%s %s cmd_size out of max\n", - extconf->name, propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - for (j = 0; j < cmd_size; j++) { - ret = of_property_read_u32_index( - of_node, propname, - (i+2+j), &val); - if (ret) { - EXTERR("get %s %s failed\n", - extconf->name, - propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - init_table[i+2+j] = (unsigned char)val; - } - index = init_table[i+2]; + index = table[i+2]; if (index < LCD_EXTERN_GPIO_NUM_MAX) lcd_extern_gpio_probe(index); - i += (cmd_size + 2); - } else { - ret = of_property_read_u32_index( - of_node, propname, (i+1), &val); - init_table[i+1] = val; - cmd_size = val; - if (cmd_size == 0) { - i += 2; - continue; - } - if ((i + 2 + cmd_size) >= max_len) { - EXTERR("%s %s cmd_size out of max\n", - extconf->name, propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - for (j = 0; j < cmd_size; j++) { - ret = of_property_read_u32_index( - of_node, propname, - (i+2+j), &val); - if (ret) { - EXTERR("%s %s failed\n", - extconf->name, - propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - init_table[i+2+j] = (unsigned char)val; - } - i += (cmd_size + 2); } + +init_table_dynamic_mipi_dts_next: + i += (cmd_size + 2); + step++; } + if (flag) + extconf->table_init_on_cnt = i + 2; + else + extconf->table_init_off_cnt = i + 2; break; default: break; @@ -581,68 +564,94 @@ static int lcd_extern_init_table_fixed_size_load_dts( struct lcd_extern_config_s *extconf, int flag) { unsigned char cmd_size, index; - int i, j, val, max_len, step = 0, ret = 0; - unsigned char *init_table; + int i = 0, j, val, max_len, step = 0, ret = 0; + unsigned char *table; char propname[20]; cmd_size = extconf->cmd_size; if (flag) { - init_table = extconf->table_init_on; + table = table_init_on_dft; max_len = LCD_EXTERN_INIT_ON_MAX; sprintf(propname, "init_on"); } else { - init_table = extconf->table_init_off; + table = table_init_off_dft; max_len = LCD_EXTERN_INIT_OFF_MAX; sprintf(propname, "init_off"); } + if (table == NULL) { + EXTERR("%s: init_table is null\n", __func__); + return -1; + } - i = 0; while (i < max_len) { /* group detect */ - if ((i + cmd_size) >= max_len) { - EXTERR("%s %s cmd_size out of max\n", - extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; - break; + if ((i + cmd_size) > max_len) { + EXTERR("%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) { - EXTERR("get %s %s failed, step %d\n", + EXTERR("%s: get %s failed, step %d\n", extconf->name, propname, step); - init_table[i] = LCD_EXTERN_INIT_END; + table[i] = LCD_EXT_CMD_TYPE_END; return -1; } - init_table[i+j] = (unsigned char)val; + table[i+j] = (unsigned char)val; } - if (init_table[i] == LCD_EXTERN_INIT_END) { + if (table[i] == LCD_EXT_CMD_TYPE_END) break; - } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) { + if (table[i] == LCD_EXT_CMD_TYPE_GPIO) { /* gpio probe */ - index = init_table[i+1]; + index = table[i+1]; if (index < LCD_EXTERN_GPIO_NUM_MAX) lcd_extern_gpio_probe(index); } - step++; i += cmd_size; + step++; } + if (flag) + extconf->table_init_on_cnt = i + cmd_size; + else + extconf->table_init_off_cnt = i + cmd_size; + return 0; } static int lcd_extern_get_config_dts(struct device_node *of_node, struct lcd_extern_config_s *extconf) { - int ret; - int val; + unsigned int ext_index = LCD_EXTERN_INDEX_INVALID; + char ext_propname[20]; + struct device_node *child; const char *str; + int val; + int ret; extconf->index = LCD_EXTERN_INDEX_INVALID; extconf->type = LCD_EXTERN_MAX; extconf->status = 0; extconf->table_init_loaded = 0; - ret = of_property_read_u32(of_node, "index", &val); + aml_lcd_notifier_call_chain(LCD_EVENT_EXTERN_SEL, &ext_index); + if (ext_index == LCD_EXTERN_INDEX_INVALID) { + EXTPR("%s: invalid index\n", __func__); + return -1; + } + sprintf(ext_propname, "extern_%d", ext_index); + if (lcd_debug_print_flag) + EXTPR("%s: %s\n", __func__, ext_propname); + + child = of_get_child_by_name(of_node, ext_propname); + if (child == NULL) { + EXTERR("failed to get %s\n", ext_propname); + return -1; + } + + ret = of_property_read_u32(child, "index", &val); if (ret) { EXTERR("get index failed, exit\n"); return -1; @@ -654,7 +663,7 @@ static int lcd_extern_get_config_dts(struct device_node *of_node, return -1; } - ret = of_property_read_string(of_node, "status", &str); + ret = of_property_read_string(child, "status", &str); if (ret) { EXTERR("get index %d status failed\n", extconf->index); return -1; @@ -666,7 +675,7 @@ static int lcd_extern_get_config_dts(struct device_node *of_node, else return -1; - ret = of_property_read_string(of_node, "extern_name", &str); + ret = of_property_read_string(child, "extern_name", &str); if (ret) { EXTERR("get extern_name failed\n"); strncpy(extconf->name, "none", LCD_EXTERN_NAME_LEN_MAX); @@ -677,212 +686,199 @@ static int lcd_extern_get_config_dts(struct device_node *of_node, extconf->name[LCD_EXTERN_NAME_LEN_MAX-1] = '\0'; EXTPR("load config: %s[%d]\n", extconf->name, extconf->index); - ret = of_property_read_u32(of_node, "type", &extconf->type); + ret = of_property_read_u32(child, "type", &extconf->type); if (ret) { extconf->type = LCD_EXTERN_MAX; - EXTERR("get type failed, exit\n"); + EXTERR("%s: get type failed, exit\n", extconf->name); return -1; } switch (extconf->type) { case LCD_EXTERN_I2C: - if (extconf->i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) - EXTERR("get %s i2c_bus failed\n", extconf->name); + if (extconf->i2c_bus == LCD_EXT_I2C_BUS_INVALID) + EXTERR("%s: get i2c_bus failed\n", extconf->name); if (lcd_debug_print_flag) { - EXTPR("%s i2c_bus=%d\n", + EXTPR("%s: i2c_bus = %d\n", extconf->name, extconf->i2c_bus); } - ret = of_property_read_u32(of_node, "i2c_address", &val); + ret = of_property_read_u32(child, "i2c_address", &val); if (ret) { - EXTERR("get %s i2c_address failed, exit\n", + EXTERR("%s: get i2c_address failed, exit\n", extconf->name); - extconf->i2c_addr = 0xff; + extconf->i2c_addr = LCD_EXT_I2C_ADDR_INVALID; return -1; } extconf->i2c_addr = (unsigned char)val; if (lcd_debug_print_flag) { - EXTPR("%s i2c_address=0x%02x\n", + EXTPR("%s: i2c_address = 0x%02x\n", extconf->name, extconf->i2c_addr); } - ret = of_property_read_u32(of_node, "i2c_second_address", &val); + ret = of_property_read_u32(child, "i2c_address2", &val); if (ret) { - EXTPR("get %s i2c_second_address failed\n", - extconf->name); - extconf->i2c_addr2 = 0xff; + ret = of_property_read_u32(child, + "i2c_second_address", &val); + if (ret) { + EXTPR("%s: no i2c_address2 exist\n", + extconf->name); + extconf->i2c_addr2 = LCD_EXT_I2C_ADDR_INVALID; + } else { + extconf->i2c_addr2 = (unsigned char)val; + } } else { extconf->i2c_addr2 = (unsigned char)val; } if (lcd_debug_print_flag) { - EXTPR("%s i2c_second_address=0x%02x\n", + EXTPR("%s: i2c_address2 = 0x%02x\n", extconf->name, extconf->i2c_addr2); } - ret = of_property_read_u32(of_node, "cmd_size", &val); + ret = of_property_read_u32(child, "cmd_size", &val); if (ret) { - if (extconf->index == 0) { - EXTERR("get %s cmd_size failed\n", - extconf->name); - } else { - EXTPR("%s no cmd_size\n", extconf->name); - } + EXTPR("%s: no cmd_size\n", extconf->name); extconf->cmd_size = 0; } else { extconf->cmd_size = (unsigned char)val; } if (lcd_debug_print_flag) { - EXTPR("%s cmd_size=%d\n", + EXTPR("%s: cmd_size = %d\n", extconf->name, extconf->cmd_size); } - if (extconf->cmd_size <= 1) { - if (extconf->index == 0) { - EXTERR("cmd_size %d is invalid\n", - extconf->cmd_size); - } + if (extconf->cmd_size == 0) break; - } - if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) { + if (extconf->cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) { ret = lcd_extern_init_table_dynamic_size_load_dts( - of_node, extconf, 1); + child, extconf, 1); if (ret) break; ret = lcd_extern_init_table_dynamic_size_load_dts( - of_node, extconf, 0); + child, extconf, 0); } else { ret = lcd_extern_init_table_fixed_size_load_dts( - of_node, extconf, 1); + child, extconf, 1); if (ret) break; ret = lcd_extern_init_table_fixed_size_load_dts( - of_node, extconf, 0); + child, extconf, 0); } if (ret == 0) extconf->table_init_loaded = 1; break; case LCD_EXTERN_SPI: - ret = of_property_read_u32(of_node, "gpio_spi_cs", &val); + ret = of_property_read_u32(child, "gpio_spi_cs", &val); if (ret) { - EXTERR("get %s gpio_spi_cs failed, exit\n", + EXTERR("%s: get gpio_spi_cs failed, exit\n", extconf->name); - extconf->spi_gpio_cs = LCD_EXTERN_GPIO_NUM_MAX; + extconf->spi_gpio_cs = LCD_EXT_GPIO_INVALID; return -1; } extconf->spi_gpio_cs = val; lcd_extern_gpio_probe(val); - if (lcd_debug_print_flag) - EXTPR("spi_gpio_cs: %d\n", extconf->spi_gpio_cs); - ret = of_property_read_u32(of_node, "gpio_spi_clk", &val); + if (lcd_debug_print_flag) { + EXTPR("%s: spi_gpio_cs: %d\n", + extconf->name, extconf->spi_gpio_cs); + } + ret = of_property_read_u32(child, "gpio_spi_clk", &val); if (ret) { - EXTERR("get %s gpio_spi_clk failed, exit\n", + EXTERR("%s: get gpio_spi_clk failed, exit\n", extconf->name); - extconf->spi_gpio_clk = LCD_EXTERN_GPIO_NUM_MAX; + extconf->spi_gpio_clk = LCD_EXT_GPIO_INVALID; return -1; } extconf->spi_gpio_clk = val; lcd_extern_gpio_probe(val); - if (lcd_debug_print_flag) - EXTPR("spi_gpio_clk: %d\n", extconf->spi_gpio_clk); - ret = of_property_read_u32(of_node, "gpio_spi_data", &val); + if (lcd_debug_print_flag) { + EXTPR("%s: spi_gpio_clk: %d\n", + extconf->name, extconf->spi_gpio_clk); + } + ret = of_property_read_u32(child, "gpio_spi_data", &val); if (ret) { - EXTERR("get %s gpio_spi_data failed, exit\n", + EXTERR("%s: get gpio_spi_data failed, exit\n", extconf->name); - extconf->spi_gpio_data = LCD_EXTERN_GPIO_NUM_MAX; + extconf->spi_gpio_data = LCD_EXT_GPIO_INVALID; return -1; } extconf->spi_gpio_data = val; lcd_extern_gpio_probe(val); - if (lcd_debug_print_flag) - EXTPR("spi_gpio_data: %d\n", extconf->spi_gpio_data); - ret = of_property_read_u32(of_node, "spi_clk_freq", &val); + if (lcd_debug_print_flag) { + EXTPR("%s: spi_gpio_data: %d\n", + extconf->name, extconf->spi_gpio_data); + } + ret = of_property_read_u32(child, "spi_clk_freq", &val); if (ret) { - EXTERR("get %s spi_clk_freq failed, default to %dHz\n", - extconf->name, LCD_EXTERN_SPI_CLK_FREQ_DFT); - extconf->spi_clk_freq = LCD_EXTERN_SPI_CLK_FREQ_DFT; + EXTERR( + "%s: get spi_clk_freq failed, default to %dKHz\n", + extconf->name, LCD_EXT_SPI_CLK_FREQ_DFT); + extconf->spi_clk_freq = LCD_EXT_SPI_CLK_FREQ_DFT; } else { extconf->spi_clk_freq = val; - if (lcd_debug_print_flag) { - EXTPR("spi_clk_freq: %dHz\n", - extconf->spi_clk_freq); - } } - ret = of_property_read_u32(of_node, "spi_clk_pol", &val); + ret = of_property_read_u32(child, "spi_clk_pol", &val); if (ret) { - EXTERR("get %s spi_clk_pol failed, default to 1\n", + EXTERR("%s: get spi_clk_pol failed, default to 1\n", extconf->name); extconf->spi_clk_pol = 1; } else { extconf->spi_clk_pol = (unsigned char)val; - if (lcd_debug_print_flag) { - EXTPR("spi_clk_pol: %dHz\n", - extconf->spi_clk_pol); - } } - ret = of_property_read_u32(of_node, "cmd_size", &val); + if (lcd_debug_print_flag) { + EXTPR("%s: spi_clk_freq: %dKHz, spi_clk_pol: %d\n", + extconf->name, extconf->spi_clk_freq, + extconf->spi_clk_pol); + } + ret = of_property_read_u32(child, "cmd_size", &val); if (ret) { - if (extconf->index == 0) { - EXTERR("get %s cmd_size failed\n", - extconf->name); - } else { - EXTPR("%s no cmd_size\n", extconf->name); - } + EXTPR("%s: no cmd_size\n", extconf->name); extconf->cmd_size = 0; } else { extconf->cmd_size = (unsigned char)val; } if (lcd_debug_print_flag) { - EXTPR("%s cmd_size=%d\n", + EXTPR("%s: cmd_size: %d\n", extconf->name, extconf->cmd_size); } - if (extconf->cmd_size <= 1) { - if (extconf->index == 0) { - EXTERR("cmd_size %d is invalid\n", - extconf->cmd_size); - } + if (extconf->cmd_size == 0) break; - } - if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) { + if (extconf->cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) { ret = lcd_extern_init_table_dynamic_size_load_dts( - of_node, extconf, 1); + child, extconf, 1); if (ret) break; ret = lcd_extern_init_table_dynamic_size_load_dts( - of_node, extconf, 0); + child, extconf, 0); } else { ret = lcd_extern_init_table_fixed_size_load_dts( - of_node, extconf, 1); + child, extconf, 1); if (ret) break; ret = lcd_extern_init_table_fixed_size_load_dts( - of_node, extconf, 0); + child, extconf, 0); } if (ret == 0) extconf->table_init_loaded = 1; break; case LCD_EXTERN_MIPI: - ret = of_property_read_u32(of_node, "cmd_size", &val); + ret = of_property_read_u32(child, "cmd_size", &val); if (ret) { - EXTPR("%s no cmd_size\n", extconf->name); + EXTPR("%s: no cmd_size\n", extconf->name); extconf->cmd_size = 0; } else { extconf->cmd_size = (unsigned char)val; } if (lcd_debug_print_flag) { - EXTPR("%s(%d) cmd_size=%d\n", - extconf->name, extconf->index, - extconf->cmd_size); + EXTPR("%s: cmd_size = %d\n", + extconf->name, extconf->cmd_size); } - if (extconf->cmd_size != LCD_EXTERN_CMD_SIZE_DYNAMIC) { - EXTERR("cmd_size %d is invalid\n", - extconf->cmd_size); + if (extconf->cmd_size != LCD_EXT_CMD_SIZE_DYNAMIC) break; - } + ret = lcd_extern_init_table_dynamic_size_load_dts( - of_node, extconf, 1); + child, extconf, 1); if (ret) break; ret = lcd_extern_init_table_dynamic_size_load_dts( - of_node, extconf, 0); + child, extconf, 0); if (ret == 0) extconf->table_init_loaded = 1; break; @@ -900,60 +896,63 @@ static int lcd_extern_init_table_dynamic_size_load_unifykey( { unsigned char cmd_size = 0; unsigned char index; - int i, j, max_len, ret = 0; - unsigned char *init_table, *buf; + int i = 0, j, max_len, ret = 0; + unsigned char *table, *buf; char propname[20]; if (flag) { - init_table = extconf->table_init_on; + table = table_init_on_dft; max_len = LCD_EXTERN_INIT_ON_MAX; sprintf(propname, "init_on"); buf = p; } else { - init_table = extconf->table_init_off; + table = table_init_off_dft; max_len = LCD_EXTERN_INIT_OFF_MAX; sprintf(propname, "init_off"); buf = p + extconf->table_init_on_cnt; } + if (table == NULL) { + EXTERR("%s: init_table is null\n", __func__); + return -1; + } + switch (extconf->type) { case LCD_EXTERN_I2C: case LCD_EXTERN_SPI: - i = 0; - while ((i + 1) < max_len) { /* type & cmd_size detect */ - /* step1: type */ + while ((i + 1) < max_len) { + /* type */ len += 1; ret = lcd_unifykey_len_check(key_len, len); if (ret) { - EXTERR("get %s %s failed\n", + EXTERR("%s: get %s failed\n", extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } - init_table[i] = *(buf + LCD_UKEY_EXT_INIT + i); - if (init_table[i] == LCD_EXTERN_INIT_END) - break; - - /* step2: cmd_size */ + table[i] = *(buf + LCD_UKEY_EXT_INIT + i); + /* cmd_size */ len += 1; ret = lcd_unifykey_len_check(key_len, len); if (ret) { - EXTERR("get %s %s failed\n", + EXTERR("%s: get %s failed\n", extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; - init_table[i+1] = 0; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } - init_table[i+1] = *(buf + LCD_UKEY_EXT_INIT + i + 1); - cmd_size = init_table[i+1]; - if (cmd_size == 0) { - i += 2; - continue; - } + table[i+1] = *(buf + LCD_UKEY_EXT_INIT + i + 1); + cmd_size = table[i+1]; + + if (table[i] == LCD_EXT_CMD_TYPE_END) + break; + if (cmd_size == 0) + goto init_table_dynamic_i2c_spi_ukey_next; if ((i + 2 + cmd_size) > max_len) { - EXTERR("%s %s cmd_size out of max\n", + EXTERR("%s: %s cmd_size out of support\n", extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; - init_table[i+1] = 0; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } @@ -961,147 +960,100 @@ static int lcd_extern_init_table_dynamic_size_load_unifykey( len += cmd_size; ret = lcd_unifykey_len_check(key_len, len); if (ret) { - EXTERR("get %s %s failed\n", + EXTERR("%s: get %s failed\n", extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; - for (j = 0; j < cmd_size; j++) - init_table[i+2+j] = 0x0; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } for (j = 0; j < cmd_size; j++) { - init_table[i+2+j] = + table[i+2+j] = *(buf + LCD_UKEY_EXT_INIT + i + 2 + j); } - if (init_table[i] == LCD_EXTERN_INIT_END) { - break; - } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) { + + if (table[i] == LCD_EXT_CMD_TYPE_GPIO) { /* gpio probe */ - index = init_table[i+1]; + index = table[i+1]; if (index < LCD_EXTERN_GPIO_NUM_MAX) lcd_extern_gpio_probe(index); } +init_table_dynamic_i2c_spi_ukey_next: i += (cmd_size + 2); } if (flag) extconf->table_init_on_cnt = i + 2; + else + extconf->table_init_off_cnt = i + 2; break; case LCD_EXTERN_MIPI: - i = 0; - while ((i + 1) < max_len) { /* type & cmd_size detect */ - /* step1: type */ + while ((i + 1) < max_len) { + /* type */ len += 1; ret = lcd_unifykey_len_check(key_len, len); if (ret) { - EXTERR("get %s %s failed\n", + EXTERR("%s: get %s failed\n", extconf->name, propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; return -1; } - init_table[i] = *(buf + LCD_UKEY_EXT_INIT + i); - if (init_table[i] == 0xff) { - len += 1; - ret = lcd_unifykey_len_check(key_len, len); - if (ret) { - EXTERR("get %s %s failed\n", - extconf->name, propname); - init_table[i+1] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - init_table[i+1] = - *(buf + LCD_UKEY_EXT_INIT + i + 1); - cmd_size = init_table[i+1]; - if (cmd_size == 0xff) + table[i] = *(buf + LCD_UKEY_EXT_INIT + i); + /* cmd_size */ + len += 1; + ret = lcd_unifykey_len_check(key_len, len); + if (ret) { + EXTERR("%s: get %s failed\n", + extconf->name, propname); + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; + return -1; + } + table[i+1] = *(buf + LCD_UKEY_EXT_INIT + i + 1); + cmd_size = table[i+1]; + + if (table[i] == LCD_EXT_CMD_TYPE_END) { + if ((cmd_size == 0xff) || (cmd_size == 0)) break; - i += 2; - } else if (init_table[i] == 0xf0) { - len += 1; - ret = lcd_unifykey_len_check(key_len, len); - if (ret) { - EXTERR("get %s %s failed\n", - extconf->name, propname); - init_table[i+1] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - init_table[i+1] = - *(buf + LCD_UKEY_EXT_INIT + i + 1); + cmd_size = 0; + } + if (cmd_size == 0) + goto init_table_dynamic_mipi_ukey_next; + if ((i + 2 + cmd_size) > max_len) { + EXTERR("%s: %s cmd_size out of max\n", + extconf->name, propname); + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; + return -1; + } + + /* data */ + len += cmd_size; + ret = lcd_unifykey_len_check(key_len, len); + if (ret) { + EXTERR("%s: get %s failed\n", + extconf->name, propname); + table[i] = LCD_EXT_CMD_TYPE_END; + table[i+1] = 0; + return -1; + } + for (j = 0; j < cmd_size; j++) { + table[i+2+j] = + *(buf + LCD_UKEY_EXT_INIT + i + 2 + j); + } + + if (table[i] == LCD_EXT_CMD_TYPE_GPIO) { /* gpio probe */ - cmd_size = *(buf + LCD_UKEY_EXT_INIT + i + 1); - if (cmd_size < 3) { - EXTERR("%s %s wrong cmd_size %d gpio\n", - extconf->name, propname, - cmd_size); - return -1; - } - if ((i + 2 + cmd_size) >= max_len) { - EXTERR("%s %s cmd_size out of max\n", - extconf->name, propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - len += cmd_size; - ret = lcd_unifykey_len_check(key_len, len); - if (ret) { - EXTERR("get %s %s failed\n", - extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; - for (j = 0; j < cmd_size; j++) - init_table[i+2+j] = 0x0; - return -1; - } - for (j = 0; j < cmd_size; j++) { - init_table[i+2+j] = *(buf + - LCD_UKEY_EXT_INIT + i + 2 + j); - } - index = init_table[i+2]; + index = table[i+2]; if (index < LCD_EXTERN_GPIO_NUM_MAX) lcd_extern_gpio_probe(index); - i += (cmd_size + 2); - } else { - len += 1; - ret = lcd_unifykey_len_check(key_len, len); - if (ret) { - EXTERR("get %s %s failed\n", - extconf->name, propname); - init_table[i+1] = 0xff; - return -1; - } - init_table[i+1] = *(buf + LCD_UKEY_EXT_INIT - + i + 1); - cmd_size = *(buf + LCD_UKEY_EXT_INIT + i + 1); - if (cmd_size == 0) { - i += 2; - continue; - } - if ((i + 2 + cmd_size) >= max_len) { - EXTERR("%s %s cmd_size out of max\n", - extconf->name, propname); - init_table[i] = 0xff; - init_table[i+1] = 0xff; - return -1; - } - len += cmd_size; - ret = lcd_unifykey_len_check(key_len, len); - if (ret) { - EXTERR("get %s %s failed\n", - extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; - for (j = 0; j < cmd_size; j++) - init_table[i+2+j] = 0xff; - return -1; - } - for (j = 0; j < cmd_size; j++) { - init_table[i+2+j] = *(buf + - LCD_UKEY_EXT_INIT + i + 2 + j); - } - i += (cmd_size + 2); } +init_table_dynamic_mipi_ukey_next: + i += (cmd_size + 2); } if (flag) extconf->table_init_on_cnt = i + 2; + else + extconf->table_init_off_cnt = i + 2; break; default: break; @@ -1116,47 +1068,51 @@ static int lcd_extern_init_table_fixed_size_load_unifykey( { unsigned char cmd_size; unsigned char index; - int i, j, max_len, ret = 0; - unsigned char *init_table, *buf; + int i = 0, j, max_len, ret = 0; + unsigned char *table, *buf; char propname[20]; cmd_size = extconf->cmd_size; if (flag) { - init_table = extconf->table_init_on; + table = table_init_on_dft; max_len = LCD_EXTERN_INIT_ON_MAX; sprintf(propname, "init_on"); buf = p; } else { - init_table = extconf->table_init_off; + table = table_init_off_dft; max_len = LCD_EXTERN_INIT_OFF_MAX; sprintf(propname, "init_off"); buf = p + extconf->table_init_on_cnt; } + if (table == NULL) { + EXTERR("%s: init_table is null\n", __func__); + return -1; + } - i = 0; while (i < max_len) { - if ((i + cmd_size) >= max_len) { - EXTERR("%s %s cmd_size out of max\n", + if ((i + cmd_size) > max_len) { + EXTERR("%s: %s cmd_size out of max\n", extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; + table[i] = LCD_EXT_CMD_TYPE_END; return -1; } len += cmd_size; ret = lcd_unifykey_len_check(key_len, len); if (ret) { - EXTERR("get %s %s failed\n", + EXTERR("%s: get %s failed\n", extconf->name, propname); - init_table[i] = LCD_EXTERN_INIT_END; + table[i] = LCD_EXT_CMD_TYPE_END; + for (j = 1; j < cmd_size; j++) + table[i+j] = 0; return -1; } for (j = 0; j < cmd_size; j++) - init_table[i+j] = *(buf + - LCD_UKEY_EXT_INIT + i + j); - if (init_table[i] == LCD_EXTERN_INIT_END) { + table[i+j] = *(buf + LCD_UKEY_EXT_INIT + i + j); + if (table[i] == LCD_EXT_CMD_TYPE_END) break; - } else if (init_table[i] == LCD_EXTERN_INIT_GPIO) { + if (table[i] == LCD_EXT_CMD_TYPE_GPIO) { /* gpio probe */ - index = init_table[i+1]; + index = table[i+1]; if (index < LCD_EXTERN_GPIO_NUM_MAX) lcd_extern_gpio_probe(index); } @@ -1164,6 +1120,8 @@ static int lcd_extern_init_table_fixed_size_load_unifykey( } if (flag) extconf->table_init_on_cnt = i + cmd_size; + else + extconf->table_init_off_cnt = i + cmd_size; return 0; } @@ -1236,17 +1194,19 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf) extconf->i2c_addr = *(p + LCD_UKEY_EXT_TYPE_VAL_0); extconf->i2c_addr2 = *(p + LCD_UKEY_EXT_TYPE_VAL_1); /*extconf->i2c_bus = *(p + LCD_UKEY_EXT_TYPE_VAL_2);*/ - if (extconf->i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) - EXTERR("get %s i2c_bus failed\n", extconf->name); + if (extconf->i2c_bus == LCD_EXT_I2C_BUS_MAX) + EXTERR("%s: get i2c_bus failed\n", extconf->name); extconf->cmd_size = *(p + LCD_UKEY_EXT_TYPE_VAL_3); + if (lcd_debug_print_flag) { + EXTPR("%s: cmd_size = %d\n", + extconf->name, extconf->cmd_size); + } /* init */ - if (extconf->cmd_size <= 1) { - EXTERR("cmd_size %d is invalid\n", extconf->cmd_size); + if (extconf->cmd_size == 0) break; - } - if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) { + if (extconf->cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) { ret = lcd_extern_init_table_dynamic_size_load_unifykey( extconf, p, key_len, len, 1); if (ret) @@ -1266,24 +1226,24 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf) break; case LCD_EXTERN_SPI: extconf->spi_gpio_cs = *(p + LCD_UKEY_EXT_TYPE_VAL_0); - lcd_extern_gpio_probe(*(p + LCD_UKEY_EXT_TYPE_VAL_0)); + lcd_extern_gpio_probe(extconf->spi_gpio_cs); extconf->spi_gpio_clk = *(p + LCD_UKEY_EXT_TYPE_VAL_1); - lcd_extern_gpio_probe(*(p + LCD_UKEY_EXT_TYPE_VAL_1)); + lcd_extern_gpio_probe(extconf->spi_gpio_clk); extconf->spi_gpio_data = *(p + LCD_UKEY_EXT_TYPE_VAL_2); - lcd_extern_gpio_probe(*(p + LCD_UKEY_EXT_TYPE_VAL_2)); + lcd_extern_gpio_probe(extconf->spi_gpio_data); extconf->spi_clk_freq = (*(p + LCD_UKEY_EXT_TYPE_VAL_3) | - ((*(p + LCD_UKEY_EXT_TYPE_VAL_3 + 1)) << 8) | - ((*(p + LCD_UKEY_EXT_TYPE_VAL_3 + 2)) << 16) | - ((*(p + LCD_UKEY_EXT_TYPE_VAL_3 + 3)) << 24)); - extconf->spi_clk_pol = *(p + LCD_UKEY_EXT_TYPE_VAL_7); - extconf->cmd_size = *(p + LCD_UKEY_EXT_TYPE_VAL_8); + ((*(p + LCD_UKEY_EXT_TYPE_VAL_4)) << 8)); + extconf->spi_clk_pol = *(p + LCD_UKEY_EXT_TYPE_VAL_5); + extconf->cmd_size = *(p + LCD_UKEY_EXT_TYPE_VAL_6); + if (lcd_debug_print_flag) { + EXTPR("%s: cmd_size = %d\n", + extconf->name, extconf->cmd_size); + } /* init */ - if (extconf->cmd_size <= 1) { - EXTERR("cmd_size %d is invalid\n", extconf->cmd_size); + if (extconf->cmd_size == 0) break; - } - if (extconf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) { + if (extconf->cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) { ret = lcd_extern_init_table_dynamic_size_load_unifykey( extconf, p, key_len, len, 1); if (ret) @@ -1304,13 +1264,11 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf) case LCD_EXTERN_MIPI: extconf->cmd_size = *(p + LCD_UKEY_EXT_TYPE_VAL_0); if (lcd_debug_print_flag) { - EXTPR("%s cmd_size=%d\n", + EXTPR("%s: cmd_size = %d\n", extconf->name, extconf->cmd_size); } - if (extconf->cmd_size != LCD_EXTERN_CMD_SIZE_DYNAMIC) { - EXTERR("cmd_size %d is invalid\n", extconf->cmd_size); + if (extconf->cmd_size != LCD_EXT_CMD_SIZE_DYNAMIC) break; - } ret = lcd_extern_init_table_dynamic_size_load_unifykey( extconf, p, key_len, len, 1); if (ret) @@ -1328,14 +1286,61 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf) return 0; } +static int lcd_extern_table_init_dft_malloc(void) +{ + table_init_on_dft = kcalloc(LCD_EXTERN_INIT_ON_MAX, + sizeof(unsigned char), GFP_KERNEL); + if (table_init_on_dft == NULL) { + EXTERR("failed to alloc init_on_dft table\n"); + return -1; + } + table_init_off_dft = kcalloc(LCD_EXTERN_INIT_OFF_MAX, + sizeof(unsigned char), GFP_KERNEL); + if (table_init_off_dft == NULL) { + EXTERR("failed to alloc init_off_dft 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 lcd_extern_table_init_save(struct lcd_extern_config_s *extconf) +{ + if (extconf->table_init_on_cnt > 0) { + extconf->table_init_on = kcalloc(extconf->table_init_on_cnt, + sizeof(unsigned char), GFP_KERNEL); + if (extconf->table_init_on == NULL) { + EXTERR("failed to alloc init_on table\n"); + return -1; + } + memcpy(extconf->table_init_on, table_init_on_dft, + extconf->table_init_on_cnt*sizeof(unsigned char)); + } + if (extconf->table_init_off_cnt > 0) { + extconf->table_init_off = kcalloc(extconf->table_init_off_cnt, + sizeof(unsigned char), GFP_KERNEL); + if (extconf->table_init_off == NULL) { + EXTERR("failed to alloc init_off table\n"); + kfree(extconf->table_init_on); + return -1; + } + memcpy(extconf->table_init_off, table_init_off_dft, + extconf->table_init_off_cnt*sizeof(unsigned char)); + } + + return 0; +} + static int lcd_extern_get_config(void) { - struct device_node *child; - unsigned int ext_index = LCD_EXTERN_INDEX_INVALID; - char ext_propname[20]; unsigned int extern_para[5]; const char *str; - int load_id = 0; + unsigned int load_id = 0; int ret; if (lcd_extern_dev->of_node == NULL) { @@ -1343,35 +1348,21 @@ static int lcd_extern_get_config(void) return -1; } - lcd_extern_config.table_init_on = - kzalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX, - GFP_KERNEL); - if (lcd_extern_config.table_init_on == NULL) { - EXTERR("failed to alloc default init table\n"); - return -1; - } - lcd_extern_config.table_init_off = - kzalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX, - GFP_KERNEL); - if (lcd_extern_config.table_init_off == NULL) { - EXTERR("failed to alloc default init table\n"); - kfree(lcd_extern_config.table_init_on); + ret = lcd_extern_table_init_dft_malloc(); + if (ret) return -1; - } - lcd_extern_config.table_init_on[0] = LCD_EXTERN_INIT_END; - lcd_extern_config.table_init_off[0] = LCD_EXTERN_INIT_END; ret = of_property_read_string(lcd_extern_dev->of_node, "i2c_bus", &str); if (ret) - lcd_extern_config.i2c_bus = LCD_EXTERN_I2C_BUS_INVALID; + lcd_extern_config.i2c_bus = LCD_EXT_I2C_BUS_MAX; else lcd_extern_config.i2c_bus = lcd_extern_get_i2c_bus_str(str); ret = of_property_read_u32_array(lcd_extern_dev->of_node, "i2c_gpio", &extern_para[0], 2); if (ret) { - lcd_extern_config.i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX; - lcd_extern_config.i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX; + lcd_extern_config.i2c_sck_gpio = LCD_EXT_GPIO_INVALID; + lcd_extern_config.i2c_sda_gpio = LCD_EXT_GPIO_INVALID; } else { lcd_extern_config.i2c_sck_gpio = (unsigned char)extern_para[0]; lcd_extern_config.i2c_sda_gpio = (unsigned char)extern_para[1]; @@ -1416,39 +1407,46 @@ static int lcd_extern_get_config(void) EXTPR("%s from unifykey\n", __func__); lcd_ext_config_load = 1; ret = lcd_extern_get_config_unifykey(&lcd_extern_config); - if (ret == 0) - lcd_extern_add_driver(&lcd_extern_config); } else { #ifdef CONFIG_OF - aml_lcd_notifier_call_chain(LCD_EVENT_EXTERN_SEL, &ext_index); - if (ext_index == LCD_EXTERN_INDEX_INVALID) { - EXTERR("%s: invalid index\n", __func__); - return -1; - } - sprintf(ext_propname, "extern_%d", ext_index); - EXTPR("%s %s from dts\n", __func__, ext_propname); + EXTPR("%s from dts\n", __func__); lcd_ext_config_load = 0; - child = of_get_child_by_name(lcd_extern_dev->of_node, - ext_propname); - if (child == NULL) { - EXTERR("failed to get %s\n", ext_propname); - return -1; - } - ret = lcd_extern_get_config_dts(child, &lcd_extern_config); - if (ret == 0) - lcd_extern_add_driver(&lcd_extern_config); + ret = lcd_extern_get_config_dts(lcd_extern_dev->of_node, + &lcd_extern_config); #endif } + if (ret) + goto lcd_extern_get_config_err; + if (lcd_extern_config.table_init_loaded > 0) { + ret = lcd_extern_table_init_save(&lcd_extern_config); + if (ret) + goto lcd_extern_get_config_err; + } + + kfree(table_init_on_dft); + kfree(table_init_off_dft); return 0; + +lcd_extern_get_config_err: + kfree(table_init_on_dft); + kfree(table_init_off_dft); + return -1; } static int lcd_extern_add_i2c(struct aml_lcd_extern_driver_s *ext_drv) { - int ret = 0; + int ret = -1; if (strcmp(ext_drv->config->name, "ext_default") == 0) { - ret = aml_lcd_extern_default_probe(ext_drv); + if (ext_drv->config->cmd_size < 2) { + EXTERR("%s: cmd_size %d is invalid\n", + ext_drv->config->name, + ext_drv->config->cmd_size); + ret = -1; + } else { + ret = aml_lcd_extern_default_probe(ext_drv); + } } else if (strcmp(ext_drv->config->name, "i2c_T5800Q") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q ret = aml_lcd_extern_i2c_T5800Q_probe(ext_drv); @@ -1465,6 +1463,10 @@ static int lcd_extern_add_i2c(struct aml_lcd_extern_driver_s *ext_drv) #ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439 ret = aml_lcd_extern_i2c_DLPC3439_probe(ext_drv); #endif + } else if (strcmp(ext_drv->config->name, "i2c_ANX6862_7911") == 0) { +#ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6862_7911 + ret = aml_lcd_extern_i2c_ANX6862_7911_probe(ext_drv); +#endif } else { EXTERR("invalid driver name: %s\n", ext_drv->config->name); ret = -1; @@ -1477,7 +1479,14 @@ static int lcd_extern_add_spi(struct aml_lcd_extern_driver_s *ext_drv) int ret = 0; if (strcmp(ext_drv->config->name, "ext_default") == 0) { - ret = aml_lcd_extern_default_probe(ext_drv); + if (ext_drv->config->cmd_size < 2) { + EXTERR("%s: cmd_size %d is invalid\n", + ext_drv->config->name, + ext_drv->config->cmd_size); + ret = -1; + } else { + ret = aml_lcd_extern_default_probe(ext_drv); + } } else if (strcmp(ext_drv->config->name, "spi_LD070WS2") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_SPI_LD070WS2 ret = aml_lcd_extern_spi_LD070WS2_probe(ext_drv); @@ -1493,8 +1502,16 @@ static int lcd_extern_add_mipi(struct aml_lcd_extern_driver_s *ext_drv) { int ret = 0; - if (strcmp(ext_drv->config->name, "mipi_default") == 0) { - ret = aml_lcd_extern_mipi_default_probe(ext_drv); + if ((strcmp(ext_drv->config->name, "mipi_default") == 0) || + (strcmp(ext_drv->config->name, "ext_default") == 0)) { + if (ext_drv->config->cmd_size != LCD_EXT_CMD_SIZE_DYNAMIC) { + EXTERR("%s: cmd_size %d is invalid\n", + ext_drv->config->name, + ext_drv->config->cmd_size); + ret = -1; + } else { + ret = aml_lcd_extern_mipi_default_probe(ext_drv); + } } else if (strcmp(ext_drv->config->name, "mipi_N070ICN") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_N070ICN ret = aml_lcd_extern_mipi_N070ICN_probe(ext_drv); @@ -1553,6 +1570,10 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf) ext_drv->config = extconf; ext_drv->pinmux_flag = 0xff; + ext_drv->reg_read = NULL; + ext_drv->reg_write = NULL; + ext_drv->power_on = NULL; + ext_drv->power_off = NULL; switch (ext_drv->config->type) { case LCD_EXTERN_I2C: @@ -1589,30 +1610,30 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf) * debug function * ********************************************************* */ -#define EXT_LEN_MAX 300 +#define EXT_LEN_MAX 500 static void lcd_extern_init_table_dynamic_size_print( struct lcd_extern_config_s *econf, int flag) { int i, j, k, max_len; unsigned char cmd_size; char *str; - unsigned char *init_table; + unsigned char *table; str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL); if (str == NULL) { - EXTERR("lcd_extern_dynamic_size str malloc error\n"); + EXTERR("%s: str malloc error\n", __func__); return; } if (flag) { pr_info("power on:\n"); - init_table = econf->table_init_on; - max_len = LCD_EXTERN_INIT_ON_MAX; + table = econf->table_init_on; + max_len = econf->table_init_on_cnt; } else { pr_info("power off:\n"); - init_table = econf->table_init_off; - max_len = LCD_EXTERN_INIT_OFF_MAX; + table = econf->table_init_off; + max_len = econf->table_init_off_cnt; } - if (init_table == NULL) { + if (table == NULL) { EXTERR("init_table %d is NULL\n", flag); kfree(str); return; @@ -1623,63 +1644,103 @@ static void lcd_extern_init_table_dynamic_size_print( case LCD_EXTERN_I2C: case LCD_EXTERN_SPI: while ((i + 1) < max_len) { - if (init_table[i] == LCD_EXTERN_INIT_END) { + if (table[i] == LCD_EXT_CMD_TYPE_END) { pr_info(" 0x%02x,%d,\n", - init_table[i], init_table[i+1]); + table[i], table[i+1]); break; } + cmd_size = table[i+1]; - cmd_size = init_table[i+1]; k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,", - init_table[i], cmd_size); - if (cmd_size > 0) { + table[i], cmd_size); + if (cmd_size == 0) + goto init_table_dynamic_print_i2c_spi_next; + if (i + 2 + cmd_size > max_len) { + pr_info("cmd_size out of support\n"); + break; + } + + if ((table[i] == LCD_EXT_CMD_TYPE_GPIO) || + (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) || + (table[i] == LCD_EXT_CMD_TYPE_CMD2)) { + 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) || + (table[i] == LCD_EXT_CMD_TYPE_CMD2_DELAY)) { for (j = 0; j < (cmd_size - 1); j++) { k += snprintf(str+k, EXT_LEN_MAX, - "0x%02x,", - init_table[i+2+j]); + "0x%02x,", table[i+2+j]); } snprintf(str+k, EXT_LEN_MAX, - "%d,", init_table[i+cmd_size+1]); + "%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_i2c_spi_next: pr_info("%s\n", str); i += (cmd_size + 2); } break; case LCD_EXTERN_MIPI: while ((i + 1) < max_len) { - if (init_table[i] == 0xff) { /* ctrl flag */ - cmd_size = 0; - if (init_table[i+1] == 0xff) { + cmd_size = table[i+1]; + if (table[i] == LCD_EXT_CMD_TYPE_END) { + if (cmd_size == 0xff) { pr_info(" 0x%02x,0x%02x,\n", - init_table[i], init_table[i+1]); + table[i], table[i+1]); break; } - pr_info(" 0x%02x,%d,\n", - init_table[i], init_table[i+1]); - } else if (init_table[i] == 0xf0) { /* gpio */ - cmd_size = init_table[i+DSI_CMD_SIZE_INDEX]; - k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,", - init_table[i], cmd_size); + if (cmd_size == 0) { + pr_info(" 0x%02x,%d,\n", + table[i], table[i+1]); + break; + } + cmd_size = 0; + } + + k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,", + table[i], cmd_size); + if (cmd_size == 0) + goto init_table_dynamic_print_mipi_next; + if (i + 2 + cmd_size > max_len) { + pr_info("cmd_size out of support\n"); + break; + } + + if ((table[i] == LCD_EXT_CMD_TYPE_GPIO) || + (table[i] == LCD_EXT_CMD_TYPE_DELAY)) { for (j = 0; j < cmd_size; j++) { k += snprintf(str+k, EXT_LEN_MAX, - "%d,", init_table[i+2+j]); + "%d,", table[i+2+j]); } - pr_info("%s\n", str); - } else if ((init_table[i] & 0xf) == 0x0) { + } else if ((table[i] & 0xf) == 0x0) { pr_info(" init_%s wrong data_type: 0x%02x\n", - flag ? "on" : "off", init_table[i]); + flag ? "on" : "off", table[i]); break; } else { - cmd_size = init_table[i+DSI_CMD_SIZE_INDEX]; + cmd_size = table[i+DSI_CMD_SIZE_INDEX]; k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,", - init_table[i], cmd_size); + table[i], cmd_size); for (j = 0; j < cmd_size; j++) { k += snprintf(str+k, EXT_LEN_MAX, "0x%02x,", - init_table[i+2+j]); + table[i+2+j]); } - pr_info("%s\n", str); } + +init_table_dynamic_print_mipi_next: + pr_info("%s\n", str); i += (cmd_size + 2); } break; @@ -1695,41 +1756,39 @@ static void lcd_extern_init_table_fixed_size_print( int i, j, k, max_len; unsigned char cmd_size; char *str; - unsigned char *init_table; + unsigned char *table; str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL); if (str == NULL) { - EXTERR("lcd_extern_fixed_size str malloc error\n"); + EXTERR("%s: str malloc error\n", __func__); return; } cmd_size = econf->cmd_size; if (flag) { pr_info("power on:\n"); - init_table = econf->table_init_on; - max_len = LCD_EXTERN_INIT_ON_MAX; + table = econf->table_init_on; + max_len = econf->table_init_on_cnt; } else { pr_info("power off:\n"); - init_table = econf->table_init_off; - max_len = LCD_EXTERN_INIT_OFF_MAX; + table = econf->table_init_off; + max_len = econf->table_init_off_cnt; } - if (init_table == NULL) { + if (table == NULL) { EXTERR("init_table %d is NULL\n", flag); kfree(str); return; } i = 0; - while (i < max_len) { + while ((i + cmd_size) <= max_len) { k = snprintf(str, EXT_LEN_MAX, " "); - for (j = 0; j < (cmd_size - 1); j++) { + for (j = 0; j < cmd_size; j++) { k += snprintf(str+k, EXT_LEN_MAX, " 0x%02x", - init_table[i+j]); + table[i+j]); } - snprintf(str+k, EXT_LEN_MAX, " %d", - init_table[i+cmd_size-1]); pr_info("%s\n", str); - if (init_table[i] == LCD_EXTERN_INIT_END) + if (table[i] == LCD_EXT_CMD_TYPE_END) break; i += cmd_size; } @@ -1746,21 +1805,24 @@ static ssize_t lcd_extern_info_show(struct class *class, econf = lcd_ext_driver->config; pr_info("lcd extern driver %s(%d) info:\n", econf->name, econf->index); - pr_info("status: %d\n", econf->status); + pr_info("status: %d\n", econf->status); switch (econf->type) { case LCD_EXTERN_I2C: - pr_info("type: i2c(%d)\n", econf->type); - pr_info("cmd_size: %d\n" - "i2c_addr: 0x%02x\n" - "i2c_addr2: 0x%02x\n" - "i2c_bus: %d\n" - "table_loaded: %d\n", - econf->cmd_size, econf->i2c_addr, - econf->i2c_addr2, econf->i2c_bus, - econf->table_init_loaded); + pr_info("type: i2c(%d)\n", econf->type); + pr_info("i2c_addr: 0x%02x\n" + "i2c_addr2: 0x%02x\n" + "i2c_bus: %d\n" + "table_loaded: %d\n" + "cmd_size: %d\n" + "table_init_on_cnt: %d\n" + "table_init_off_cnt: %d\n", + econf->i2c_addr, econf->i2c_addr2, econf->i2c_bus, + econf->table_init_loaded, econf->cmd_size, + econf->table_init_on_cnt, + econf->table_init_off_cnt); if (econf->cmd_size == 0) break; - if (econf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) { + if (econf->cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) { lcd_extern_init_table_dynamic_size_print(econf, 1); lcd_extern_init_table_dynamic_size_print(econf, 0); } else { @@ -1769,22 +1831,26 @@ static ssize_t lcd_extern_info_show(struct class *class, } break; case LCD_EXTERN_SPI: - pr_info("type: spi(%d)\n", econf->type); - pr_info("cmd_size: %d\n" - "spi_gpio_cs: %d\n" - "spi_gpio_clk: %d\n" - "spi_gpio_data: %d\n" - "spi_clk_freq: %dHz\n" - "spi_delay_us: %d\n" - "spi_clk_pol: %d\n" - "table_loaded: %d\n", - econf->cmd_size, econf->spi_gpio_cs, - econf->spi_gpio_clk, econf->spi_gpio_data, - econf->spi_clk_freq, econf->spi_delay_us, - econf->spi_clk_pol, econf->table_init_loaded); + pr_info("type: spi(%d)\n", econf->type); + pr_info("spi_gpio_cs: %d\n" + "spi_gpio_clk: %d\n" + "spi_gpio_data: %d\n" + "spi_clk_freq: %dKHz\n" + "spi_delay_us: %d\n" + "spi_clk_pol: %d\n" + "table_loaded: %d\n" + "cmd_size: %d\n" + "table_init_on_cnt: %d\n" + "table_init_off_cnt: %d\n", + econf->spi_gpio_cs, econf->spi_gpio_clk, + econf->spi_gpio_data, econf->spi_clk_freq, + econf->spi_delay_us, econf->spi_clk_pol, + econf->table_init_loaded, econf->cmd_size, + econf->table_init_on_cnt, + econf->table_init_off_cnt); if (econf->cmd_size == 0) break; - if (econf->cmd_size == LCD_EXTERN_CMD_SIZE_DYNAMIC) { + if (econf->cmd_size == LCD_EXT_CMD_SIZE_DYNAMIC) { lcd_extern_init_table_dynamic_size_print(econf, 1); lcd_extern_init_table_dynamic_size_print(econf, 0); } else { @@ -1794,8 +1860,15 @@ static ssize_t lcd_extern_info_show(struct class *class, break; case LCD_EXTERN_MIPI: pr_info("type: mipi(%d)\n", econf->type); - pr_info("cmd_size: %d\n", econf->cmd_size); - if (econf->cmd_size != LCD_EXTERN_CMD_SIZE_DYNAMIC) + pr_info("table_loaded: %d\n" + "cmd_size: %d\n" + "table_init_on_cnt: %d\n" + "table_init_off_cnt: %d\n", + econf->table_init_loaded, + econf->cmd_size, + econf->table_init_on_cnt, + econf->table_init_off_cnt); + if (econf->cmd_size != LCD_EXT_CMD_SIZE_DYNAMIC) break; lcd_extern_init_table_dynamic_size_print(econf, 1); lcd_extern_init_table_dynamic_size_print(econf, 0); @@ -1938,7 +2011,7 @@ static struct class_attribute lcd_extern_class_attrs[] = { __ATTR(info, 0644, lcd_extern_info_show, NULL), __ATTR(key_valid, 0444, - lcd_extern_key_valid_show, NULL), + lcd_extern_key_valid_show, NULL), __ATTR(config_load, 0444, lcd_extern_config_load_show, NULL), __ATTR(debug, 0644, @@ -1983,9 +2056,14 @@ static int remove_lcd_extern_class(void) static int aml_lcd_extern_probe(struct platform_device *pdev) { + int ret; + lcd_extern_dev = &pdev->dev; - lcd_extern_get_config(); /* also add ext_driver */ + ret = lcd_extern_get_config(); + if (ret == 0) + lcd_extern_add_driver(&lcd_extern_config); + creat_lcd_extern_class(); diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h b/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h index 9fd9212..f3f8854 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h @@ -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); diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c index 36cab44..6eedd93 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c @@ -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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c index 7bb0e75..f12cb7e 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c @@ -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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c index ed09e4d..507b357 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c @@ -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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_ST7701.c b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_ST7701.c index e2e8f0c3..15e0d79 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_ST7701.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_ST7701.c @@ -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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c index 457c6fc..654443b 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c @@ -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( diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TV070WSM.c b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TV070WSM.c index 903a36b..90ac36e 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TV070WSM.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TV070WSM.c @@ -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) diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_default.c b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_default.c index 6060897..0c96aaa 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_default.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_default.c @@ -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; diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c b/drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c index a0d025a..fe41a8e 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c @@ -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; diff --git a/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c b/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c index bd1fa32..9f80de2 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c +++ b/drivers/amlogic/media/vout/lcd/lcd_tablet/mipi_dsi_util.c @@ -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 */ - ret = of_property_read_u32_index(m_node, - propname, (i + DSI_GPIO_INDEX), &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 = 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; + } - /* 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 */ + if (type == LCD_EXT_CMD_TYPE_GPIO) { + /* probe gpio */ ret = of_property_read_u32_index(m_node, - propname, (i + DSI_CMD_SIZE_INDEX), &val); + propname, (i + 2), &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; - } - + lcd_cpu_gpio_probe(val); + } else if (type == LCD_EXT_CMD_TYPE_CHECK) { ret = of_property_read_u32_index(m_node, propname, (i + DSI_CMD_SIZE_INDEX + 1), ¶[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, ¶[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) diff --git a/include/linux/amlogic/media/vout/lcd/aml_bl_extern.h b/include/linux/amlogic/media/vout/lcd/aml_bl_extern.h index a5dd373..d4f3511 100644 --- a/include/linux/amlogic/media/vout/lcd/aml_bl_extern.h +++ b/include/linux/amlogic/media/vout/lcd/aml_bl_extern.h @@ -17,6 +17,7 @@ #ifndef _INC_AML_BL_EXTERN_H_ #define _INC_AML_BL_EXTERN_H_ +#include 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_SPI_CLK_FREQ_DFT 10000 /* default 10k */ - -#define BL_EXTERN_INIT_TABLE_MAX 500 +#define BL_EXTERN_INIT_ON_MAX 300 +#define BL_EXTERN_INIT_OFF_MAX 50 -#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 */ diff --git a/include/linux/amlogic/media/vout/lcd/aml_lcd.h b/include/linux/amlogic/media/vout/lcd/aml_lcd.h new file mode 100644 index 0000000..ab655e5 --- /dev/null +++ b/include/linux/amlogic/media/vout/lcd/aml_lcd.h @@ -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 + diff --git a/include/linux/amlogic/media/vout/lcd/aml_ldim.h b/include/linux/amlogic/media/vout/lcd/aml_ldim.h index 0ccc27f..1478ee9 100644 --- a/include/linux/amlogic/media/vout/lcd/aml_ldim.h +++ b/include/linux/amlogic/media/vout/lcd/aml_ldim.h @@ -22,6 +22,7 @@ #include #include #include +#include #include /*#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; diff --git a/include/linux/amlogic/media/vout/lcd/lcd_extern.h b/include/linux/amlogic/media/vout/lcd/lcd_extern.h index 76edb60..a979577 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_extern.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_extern.h @@ -17,6 +17,7 @@ #ifndef _INC_AML_LCD_EXTERN_H_ #define _INC_AML_LCD_EXTERN_H_ +#include 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 */ -- 2.7.4