From f713602c15b21e93897db925bed11ec46fa1035d Mon Sep 17 00:00:00 2001 From: Evoke Zhang Date: Fri, 10 Aug 2018 13:58:03 +0800 Subject: [PATCH] lcd: lcd_extern: add two i2c address support PD#169249: lcd: lcd_extern: add two i2c address support Change-Id: Ic67304cd32768f5800b3702c57527e152bb71916 Signed-off-by: Evoke Zhang --- MAINTAINERS | 4 + .../boot/dts/amlogic/mesonaxg_s400-panel.dtsi | 1 + .../boot/dts/amlogic/mesong12a_skt-panel.dtsi | 1 + .../boot/dts/amlogic/mesong12b_skt-panel.dtsi | 1 + .../boot/dts/amlogic/mesongxm_q200-panel.dtsi | 2 +- .../boot/dts/amlogic/mesontxlx_r311-panel.dtsi | 2 - drivers/amlogic/media/vout/lcd/lcd_common.c | 30 +- drivers/amlogic/media/vout/lcd/lcd_extern/Makefile | 4 +- .../media/vout/lcd/lcd_extern/ext_default.c | 277 ++++----- .../media/vout/lcd/lcd_extern/ext_i2c_dev.c | 226 ++++++++ .../media/vout/lcd/lcd_extern/i2c_DLPC3439.c | 136 +---- .../amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c | 164 +----- .../media/vout/lcd/lcd_extern/i2c_anx6345.c | 234 ++------ .../amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c | 120 +--- .../amlogic/media/vout/lcd/lcd_extern/lcd_extern.c | 641 ++++++++++----------- .../media/vout/lcd/lcd_extern/lcd_extern.dts | 99 ---- .../amlogic/media/vout/lcd/lcd_extern/lcd_extern.h | 20 +- .../media/vout/lcd/lcd_extern/mipi_KD080D13.c | 4 +- .../media/vout/lcd/lcd_extern/mipi_N070ICN.c | 4 +- .../media/vout/lcd/lcd_extern/mipi_P070ACB.c | 4 +- .../media/vout/lcd/lcd_extern/mipi_ST7701.c | 4 +- .../media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c | 4 +- .../media/vout/lcd/lcd_extern/mipi_TV070WSM.c | 4 +- .../media/vout/lcd/lcd_extern/mipi_default.c | 12 +- .../media/vout/lcd/lcd_extern/spi_LD070WS2.c | 24 +- .../media/vout/lcd/lcd_tablet/mipi_dsi_util.c | 12 +- drivers/amlogic/media/vout/lcd/lcd_vout.c | 43 +- include/linux/amlogic/media/vout/lcd/lcd_extern.h | 34 +- include/linux/amlogic/media/vout/lcd/lcd_notify.h | 1 + include/linux/amlogic/media/vout/lcd/lcd_vout.h | 1 + 30 files changed, 882 insertions(+), 1231 deletions(-) create mode 100644 drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.c delete mode 100644 drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts diff --git a/MAINTAINERS b/MAINTAINERS index 44276d6..a84a9f0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -14596,6 +14596,10 @@ AMLOGIC SOUND ADC3101 M: Renjun Xu F: Documentation/devicetree/bindings/amlogic/axg-sound-adc3010-d608mic-pcm.txt +AMLOGIC LCD EXTERN DRIVER +M: evoke zhang +F: drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.c + AMLOGIC SYSTEM AS ROOT M: Xindong Xu F: arch/arm64/boot/dts/amlogic/firmware_avb_system.dtsi diff --git a/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi index ac279f9..ae856c7 100644 --- a/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesonaxg_s400-panel.dtsi @@ -230,6 +230,7 @@ compatible = "amlogic, lcd_extern"; dev_name = "lcd_extern"; status = "okay"; + i2c_bus = "i2c_bus_1"; key_valid = <0>; extern_0{ diff --git a/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi index 8a5b9a5..622f5c3 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12a_skt-panel.dtsi @@ -399,6 +399,7 @@ compatible = "amlogic, lcd_extern"; dev_name = "lcd_extern"; status = "okay"; + i2c_bus = "i2c_bus_0"; key_valid = <0>; extern_0{ diff --git a/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi index 8caa15d..0ca4d8a 100644 --- a/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesong12b_skt-panel.dtsi @@ -255,6 +255,7 @@ compatible = "amlogic, lcd_extern"; dev_name = "lcd_extern"; status = "okay"; + i2c_bus = "i2c_bus_0"; key_valid = <0>; extern_0{ diff --git a/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi index 59fdf06..0251205 100644 --- a/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesongxm_q200-panel.dtsi @@ -89,6 +89,7 @@ compatible = "amlogic, lcd_extern"; dev_name = "lcd_extern"; status = "okay"; + i2c_bus = "i2c_bus_d"; key_valid = <0>; extern_0{ @@ -98,7 +99,6 @@ type = <0>; /* 0=i2c, 1=spi, 2=mipi */ i2c_address = <0x1c>; /* 7bit i2c address */ i2c_second_address = <0xff>; /* 0xff for none */ - i2c_bus = "i2c_bus_d"; cmd_size = <0xff>; /*0xff for dynamic cmd_size*/ /* init on/off: diff --git a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi index fce0ec3..ca4ef2c 100644 --- a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi @@ -475,7 +475,6 @@ type = <0>; /*0=i2c, 1=spi, 2=mipi*/ i2c_address = <0x1c>; /*7bit i2c_addr*/ i2c_second_address = <0xff>; - i2c_bus = "i2c_bus_c"; cmd_size = <0xff>; /*dynamic cmd_size*/ /* init on/off: @@ -509,7 +508,6 @@ status = "disabled"; type = <0>; /* 0=i2c, 1=spi, 2=mipi */ i2c_address = <0x1c>; /* 7bit i2c address */ - i2c_bus = "i2c_bus_c"; cmd_size = <9>; }; }; diff --git a/drivers/amlogic/media/vout/lcd/lcd_common.c b/drivers/amlogic/media/vout/lcd/lcd_common.c index 7af5172..e988251 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_common.c +++ b/drivers/amlogic/media/vout/lcd/lcd_common.c @@ -471,13 +471,16 @@ int lcd_power_load_from_dts(struct lcd_config_s *pconf, "power_on_step", j, &val); lcd_power->power_on_step[i].delay = val; - /* gpio probe */ + /* gpio/extern probe */ + index = lcd_power->power_on_step[i].index; switch (lcd_power->power_on_step[i].type) { case LCD_POWER_TYPE_CPU: - index = lcd_power->power_on_step[i].index; if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; + case LCD_POWER_TYPE_EXTERN: + pconf->extern_index = index; + break; default: break; } @@ -522,13 +525,17 @@ int lcd_power_load_from_dts(struct lcd_config_s *pconf, "power_off_step", j, &val); lcd_power->power_off_step[i].delay = val; - /* gpio probe */ + /* gpio/extern probe */ + index = lcd_power->power_off_step[i].index; switch (lcd_power->power_off_step[i].type) { case LCD_POWER_TYPE_CPU: - index = lcd_power->power_off_step[i].index; if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; + case LCD_POWER_TYPE_EXTERN: + if (pconf->extern_index == 0xff) + pconf->extern_index = index; + break; default: break; } @@ -591,13 +598,16 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf, (*(p + LCD_UKEY_PWR_DELAY + 5*i) | ((*(p + LCD_UKEY_PWR_DELAY + 5*i + 1)) << 8)); - /* gpio probe */ + /* gpio/extern probe */ + index = pconf->lcd_power->power_on_step[i].index; switch (pconf->lcd_power->power_on_step[i].type) { case LCD_POWER_TYPE_CPU: - index = pconf->lcd_power->power_on_step[i].index; if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; + case LCD_POWER_TYPE_EXTERN: + pconf->extern_index = index; + break; default: break; } @@ -639,13 +649,17 @@ int lcd_power_load_from_unifykey(struct lcd_config_s *pconf, (*(p + LCD_UKEY_PWR_DELAY + 5*j) | ((*(p + LCD_UKEY_PWR_DELAY + 5*j + 1)) << 8)); - /* gpio probe */ + /* gpio/extern probe */ + index = pconf->lcd_power->power_off_step[j].index; switch (pconf->lcd_power->power_off_step[j].type) { case LCD_POWER_TYPE_CPU: - index = pconf->lcd_power->power_off_step[j].index; if (index < LCD_CPU_GPIO_NUM_MAX) lcd_cpu_gpio_probe(index); break; + case LCD_POWER_TYPE_EXTERN: + if (pconf->extern_index == 0xff) + pconf->extern_index = index; + break; default: break; } diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile b/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile index 91bc8b3..fed2ce1 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/Makefile @@ -1,7 +1,7 @@ -obj-$(CONFIG_AMLOGIC_LCD_EXTERN) += lcd_extern.o ext_default.o mipi_default.o +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_SPI_LD070WS2) += spi_LD070WS2.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 obj-$(CONFIG_AMLOGIC_LCD_EXTERN_MIPI_TV070WSM) += mipi_TV070WSM.o obj-$(CONFIG_AMLOGIC_LCD_EXTERN_MIPI_ST7701) += mipi_ST7701.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 a509a08..5821417 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c @@ -20,7 +20,6 @@ #include #include #include -#include #include #include #include @@ -28,60 +27,14 @@ #include #include "lcd_extern.h" -#define LCD_EXTERN_INDEX 0 #define LCD_EXTERN_NAME "ext_default" -#define LCD_EXTERN_TYPE LCD_EXTERN_I2C - -#define LCD_EXTERN_I2C_ADDR (0x1c) /* 7bit address */ -#define LCD_EXTERN_I2C_ADDR2 (0xff) /* 7bit address */ -#define LCD_EXTERN_I2C_BUS AML_I2C_MASTER_A - -#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_POL 1 +#define LCD_EXTERN_TYPE LCD_EXTERN_MAX static struct lcd_extern_config_s *ext_config; -static struct aml_lcd_extern_i2c_dev_s *i2c_device; - -#define LCD_EXTERN_CMD_SIZE 9 -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 */ -}; - -static unsigned char init_off_table[] = { - 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */ -}; - -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, - } - }; +static struct aml_lcd_extern_i2c_dev_s *i2c0_dev; +static struct aml_lcd_extern_i2c_dev_s *i2c1_dev; - ret = i2c_transfer(i2client->adapter, msg, 1); - if (ret < 0) - EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr); - - return ret; -} static void set_lcd_csb(unsigned int v) { @@ -154,15 +107,61 @@ static int lcd_extern_spi_write(unsigned char *buf, int len) 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; + switch (ext_config->type) { + case LCD_EXTERN_I2C: + 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; + break; + case LCD_EXTERN_SPI: + EXTPR("not support\n"); + break; + default: + break; + } + 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; + switch (ext_config->type) { + case LCD_EXTERN_I2C: + 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); + break; + case LCD_EXTERN_SPI: + lcd_extern_spi_write(tmp, 2); + break; + default: + break; + } + return ret; } @@ -219,17 +218,23 @@ static int lcd_extern_power_cmd_dynamic_size(unsigned char *init_table, if (init_table[i+4] > 0) mdelay(init_table[i+4]); } else if (type == LCD_EXTERN_INIT_CMD) { - if (i2c_device == NULL) { - EXTERR("invalid i2c device\n"); + if (i2c0_dev == NULL) { + EXTERR("invalid i2c0 device\n"); return -1; } - ret = lcd_extern_i2c_write( - i2c_device->client, + 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) { - EXTPR("%s not support cmd2\n", __func__); + 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]); } else { EXTERR("%s(%d: %s): type %d invalid\n", __func__, ext_config->index, @@ -332,15 +337,19 @@ static int lcd_extern_power_cmd_fixed_size(unsigned char *init_table, int flag) init_table[i+2]); } } else if (type == LCD_EXTERN_INIT_CMD) { - if (i2c_device == NULL) { - EXTERR("invalid i2c device\n"); + if (i2c0_dev == NULL) { + EXTERR("invalid i2c0 device\n"); return -1; } - ret = lcd_extern_i2c_write( - i2c_device->client, + ret = lcd_extern_i2c_write(i2c0_dev->client, &init_table[i+1], (cmd_size-2)); } else if (type == LCD_EXTERN_INIT_CMD2) { - EXTPR("%s not support cmd2\n", __func__); + 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)); } else { EXTERR("%s(%d: %s): type %d invalid\n", __func__, ext_config->index, @@ -435,21 +444,21 @@ static int lcd_extern_power_ctrl(int flag) return ret; } -static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_on(void) { int ret; - lcd_extern_pinmux_set(ext_drv, 1); + lcd_extern_pinmux_set(1); ret = lcd_extern_power_ctrl(1); return ret; } -static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_off(void) { int ret; - lcd_extern_pinmux_set(ext_drv, 0); ret = lcd_extern_power_ctrl(0); + lcd_extern_pinmux_set(0); return ret; } @@ -460,35 +469,9 @@ 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 dts */ - 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.cmd_size = LCD_EXTERN_CMD_SIZE; - switch (ext_drv->config.type) { - case LCD_EXTERN_I2C: - ext_drv->config.i2c_addr = LCD_EXTERN_I2C_ADDR; - ext_drv->config.i2c_addr2 = LCD_EXTERN_I2C_ADDR2; - ext_drv->config.i2c_bus = LCD_EXTERN_I2C_BUS; - break; - case LCD_EXTERN_SPI: - ext_drv->config.spi_gpio_cs = SPI_GPIO_CS; - ext_drv->config.spi_gpio_clk = SPI_GPIO_CLK; - ext_drv->config.spi_gpio_data = SPI_GPIO_DATA; - ext_drv->config.spi_clk_freq = SPI_CLK_FREQ; - ext_drv->config.spi_clk_pol = SPI_CLK_POL; - break; - default: - break; - } - } - if (ext_drv->config.table_init_loaded == 0) { - ext_drv->config.table_init_on = init_on_table; - ext_drv->config.table_init_off = init_off_table; - } - if (ext_drv->config.type == LCD_EXTERN_SPI) { - ext_drv->config.spi_delay_us = - 1000000 / ext_drv->config.spi_clk_freq; + if (ext_drv->config->type == LCD_EXTERN_SPI) { + ext_drv->config->spi_delay_us = + 1000000 / ext_drv->config->spi_clk_freq; } ext_drv->reg_read = lcd_extern_reg_read; @@ -503,17 +486,30 @@ int aml_lcd_extern_default_probe(struct aml_lcd_extern_driver_s *ext_drv) { int ret = 0; - ext_config = &ext_drv->config; + ext_config = ext_drv->config; - switch (ext_drv->config.type) { + switch (ext_config->type) { case LCD_EXTERN_I2C: - if (i2c_device == NULL) { - EXTERR("invalid i2c device\n"); - return -1; + if (ext_config->i2c_addr < LCD_EXTERN_I2C_ADDR_INVALID) { + 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); } - if (ext_drv->config.i2c_addr != i2c_device->client->addr) { - EXTERR("invalid i2c addr\n"); - return -1; + if (ext_config->i2c_addr2 < LCD_EXTERN_I2C_ADDR_INVALID) { + 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); } break; case LCD_EXTERN_SPI: @@ -529,83 +525,12 @@ int aml_lcd_extern_default_probe(struct aml_lcd_extern_driver_s *ext_drv) return ret; } -static int lcd_extern_i2c_config_from_dts(struct device *dev, - struct aml_lcd_extern_i2c_dev_s *i2c_device) +int aml_lcd_extern_default_remove(void) { - int ret; - struct device_node *np = dev->of_node; - const char *str; - - ret = of_property_read_string(np, "dev_name", &str); - if (ret) { - EXTERR("failed to get dev_i2c_name\n"); - str = "lcd_extern_i2c_default"; - } - strcpy(i2c_device->name, str); + i2c0_dev = NULL; + i2c1_dev = NULL; + ext_config = NULL; return 0; } -static int aml_lcd_extern_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - EXTERR("I2C check functionality failed."); - return -ENODEV; - } - - i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s), - GFP_KERNEL); - if (!i2c_device) { - EXTERR("driver malloc error\n"); - return -ENOMEM; - } - i2c_device->client = client; - lcd_extern_i2c_config_from_dts(&client->dev, i2c_device); - EXTPR("I2C %s Address: 0x%02x", i2c_device->name, - i2c_device->client->addr); - - return 0; -} - -static int aml_lcd_extern_i2c_remove(struct i2c_client *client) -{ - kfree(i2c_device); - i2c_set_clientdata(client, NULL); - - return 0; -} - -static const struct i2c_device_id aml_lcd_extern_i2c_id[] = { - {"ext_default", 0}, - {} -}; - -#ifdef CONFIG_OF -static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = { - { - .compatible = "amlogic, lcd_ext_default", - }, - {}, -}; -#endif - -static struct i2c_driver aml_lcd_extern_i2c_driver = { - .probe = aml_lcd_extern_i2c_probe, - .remove = aml_lcd_extern_i2c_remove, - .id_table = aml_lcd_extern_i2c_id, - .driver = { - .name = "ext_default", - .owner = THIS_MODULE, -#ifdef CONFIG_OF - .of_match_table = aml_lcd_extern_i2c_dt_match, -#endif - }, -}; - -module_i2c_driver(aml_lcd_extern_i2c_driver); - -MODULE_AUTHOR("AMLOGIC"); -MODULE_DESCRIPTION("lcd extern driver"); -MODULE_LICENSE("GPL"); - diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.c b/drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.c new file mode 100644 index 0000000..2da1b27 --- /dev/null +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.c @@ -0,0 +1,226 @@ +/* + * drivers/amlogic/media/vout/lcd/lcd_extern/ext_i2c_dev.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" + +static struct aml_lcd_extern_i2c_dev_s *i2c_dev[LCD_EXT_I2C_DEV_MAX]; +static unsigned int i2c_dev_cnt; + +struct aml_lcd_extern_i2c_dev_s *lcd_extern_get_i2c_device(unsigned char addr) +{ + struct aml_lcd_extern_i2c_dev_s *i2c_device = NULL; + int i; + + /*pr_info("%s: addr=0x%02x\n", __func__, addr);*/ + for (i = 0; i < i2c_dev_cnt; i++) { + if (i2c_dev[i] == NULL) + break; + if (i2c_dev[i]->client->addr == addr) { + i2c_device = i2c_dev[i]; + break; + } + } + return i2c_device; +} + +int lcd_extern_i2c_write(struct i2c_client *i2client, + unsigned char *buff, unsigned int len) +{ + struct i2c_msg msg; + int ret = 0; + + if (i2client == NULL) { + EXTERR("i2client is null\n"); + return -1; + } + + msg.addr = i2client->addr; + msg.flags = 0; + msg.len = len; + msg.buf = buff; + + ret = i2c_transfer(i2client->adapter, &msg, 1); + if (ret < 0) + EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr); + + return ret; +} + +int lcd_extern_i2c_read(struct i2c_client *i2client, + unsigned char *buff, unsigned int len) +{ + struct i2c_msg msgs[2]; + int ret = 0; + + if (i2client == NULL) { + EXTERR("i2client is null\n"); + return -1; + } + + msgs[0].addr = i2client->addr; + msgs[0].flags = 0; + msgs[0].len = 1; + msgs[0].buf = buff; + msgs[1].addr = i2client->addr; + msgs[1].flags = I2C_M_RD; + msgs[1].len = len; + msgs[1].buf = buff; + + ret = i2c_transfer(i2client->adapter, msgs, 2); + if (ret < 0) { + EXTERR("%s: i2c transfer failed [addr 0x%02x]\n", + __func__, i2client->addr); + } + + return ret; +} + +static int lcd_extern_i2c_config_from_dts(struct device *dev, + struct aml_lcd_extern_i2c_dev_s *i2c_device) +{ + int ret; + struct device_node *np = dev->of_node; + const char *str; + + ret = of_property_read_string(np, "dev_name", &str); + if (ret) { + EXTERR("failed to get dev_i2c_name\n"); + strcpy(i2c_device->name, "lcd_ext_i2c0"); + } else { + strncpy(i2c_device->name, str, 30); + i2c_device->name[29] = '\0'; + } + + return 0; +} + +static int lcd_extern_i2c_dev_probe(struct i2c_client *client, + const struct i2c_device_id *id) +{ + if (i2c_dev_cnt >= LCD_EXT_I2C_DEV_MAX) { + EXTERR("i2c_dev_cnt reach max\n"); + return -ENODEV; + } + + if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { + EXTERR("i2c0_dev check functionality failed"); + return -ENODEV; + } + + i2c_dev[i2c_dev_cnt] = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s), + GFP_KERNEL); + if (!i2c_dev[i2c_dev_cnt]) { + EXTERR("i2c0_dev %d driver malloc error\n", i2c_dev_cnt); + return -ENOMEM; + } + + i2c_dev[i2c_dev_cnt]->client = client; + lcd_extern_i2c_config_from_dts(&client->dev, i2c_dev[i2c_dev_cnt]); + EXTPR("i2c_dev probe: %s address 0x%02x OK", + i2c_dev[i2c_dev_cnt]->name, + i2c_dev[i2c_dev_cnt]->client->addr); + + i2c_dev_cnt++; + + return 0; +} + +static int lcd_extern_i2c_dev_remove(struct i2c_client *client) +{ + int i; + + if (i2c_dev_cnt == 0) + return 0; + + for (i = 0; i < i2c_dev_cnt; i++) { + kfree(i2c_dev[i]); + i2c_dev[i] = NULL; + } + i2c_dev_cnt = 0; + + return 0; +} + +static const struct i2c_device_id lcd_extern_i2c_dev_id[] = { + {"lcd_ext_i2c", 0}, + {} +}; + +#ifdef CONFIG_OF +static const struct of_device_id lcd_extern_i2c_dev_dt_match[] = { + { + .compatible = "lcd_ext, i2c", + }, + {}, +}; +#endif + +static struct i2c_driver lcd_extern_i2c_dev_driver = { + .probe = lcd_extern_i2c_dev_probe, + .remove = lcd_extern_i2c_dev_remove, + .id_table = lcd_extern_i2c_dev_id, + .driver = { + .name = "lcd_ext_i2c", + .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = lcd_extern_i2c_dev_dt_match, +#endif + }, +}; + +static int __init aml_lcd_extern_i2c_dev_init(void) +{ + int ret; + + if (lcd_debug_print_flag) + EXTPR("%s\n", __func__); + + i2c_dev_cnt = 0; + + ret = i2c_add_driver(&lcd_extern_i2c_dev_driver); + if (ret) { + EXTERR("i2c0_dev driver register failed\n"); + return -ENODEV; + } + + return ret; +} + +static void __exit aml_lcd_extern_i2c_dev_exit(void) +{ + i2c_del_driver(&lcd_extern_i2c_dev_driver); +} + + +module_init(aml_lcd_extern_i2c_dev_init); +module_exit(aml_lcd_extern_i2c_dev_exit); + +MODULE_AUTHOR("AMLOGIC"); +MODULE_DESCRIPTION("lcd extern i2c device driver"); +MODULE_LICENSE("GPL"); + 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 2dd7f86..0f0281e 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c @@ -30,8 +30,12 @@ #define LCD_EXTERN_NAME "i2c_DLPC3439" +#define LCD_EXTERN_I2C_ADDR (0x1b) /* 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 *i2c_device; +static struct aml_lcd_extern_i2c_dev_s *i2c_dev; /* Write: ImageCrop: 1920x1080 @@ -56,51 +60,31 @@ static unsigned char data_4[] = {0x05, 0x00}; */ static unsigned char data_5[] = {0x07, 0x43}; -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(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_on(void) { int ret = 0; - lcd_extern_pinmux_set(ext_drv, 1); + lcd_extern_pinmux_set(1); - if (i2c_device == NULL) { + if (i2c_dev == NULL) { EXTERR("invalid i2c device\n"); return -1; } - lcd_extern_i2c_write(i2c_device->client, data_1, 9); - lcd_extern_i2c_write(i2c_device->client, data_2, 5); - lcd_extern_i2c_write(i2c_device->client, data_3, 5); - lcd_extern_i2c_write(i2c_device->client, data_4, 2); - lcd_extern_i2c_write(i2c_device->client, data_5, 2); + lcd_extern_i2c_write(i2c_dev->client, data_1, 9); + lcd_extern_i2c_write(i2c_dev->client, data_2, 5); + lcd_extern_i2c_write(i2c_dev->client, data_3, 5); + lcd_extern_i2c_write(i2c_dev->client, data_4, 2); + lcd_extern_i2c_write(i2c_dev->client, data_5, 2); EXTPR("%s\n", __func__); return ret; } -static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_off(void) { int ret = 0; - lcd_extern_pinmux_set(ext_drv, 0); + lcd_extern_pinmux_set(0); return ret; } @@ -124,15 +108,15 @@ int aml_lcd_extern_i2c_DLPC3439_probe(struct aml_lcd_extern_driver_s *ext_drv) { int ret = 0; - ext_config = &ext_drv->config; - if (i2c_device == NULL) { + ext_config = ext_drv->config; + + i2c_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr); + if (i2c_dev == NULL) { EXTERR("invalid i2c device\n"); return -1; } - if (ext_drv->config.i2c_addr != i2c_device->client->addr) { - EXTERR("invalid i2c addr\n"); - return -1; - } + EXTPR("get i2c device: %s, addr 0x%02x OK\n", + i2c_dev->name, i2c_dev->client->addr); ret = lcd_extern_driver_update(ext_drv); @@ -141,83 +125,11 @@ int aml_lcd_extern_i2c_DLPC3439_probe(struct aml_lcd_extern_driver_s *ext_drv) return ret; } -static int lcd_extern_i2c_config_from_dts(struct device *dev, - struct aml_lcd_extern_i2c_dev_s *i2c_device) +int aml_lcd_extern_i2c_DLPC3439_remove(void) { - int ret; - struct device_node *np = dev->of_node; - const char *str; - - ret = of_property_read_string(np, "dev_name", &str); - if (ret) { - EXTERR("failed to get dev_i2c_name\n"); - str = "lcd_extern_i2c_DLPC3439"; - } - strcpy(i2c_device->name, str); + i2c_dev = NULL; + ext_config = NULL; return 0; } -static int aml_lcd_extern_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - EXTERR("I2C check functionality failed."); - return -ENODEV; - } - - i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s), - GFP_KERNEL); - if (!i2c_device) { - EXTERR("driver malloc error\n"); - return -ENOMEM; - } - i2c_device->client = client; - lcd_extern_i2c_config_from_dts(&client->dev, i2c_device); - EXTPR("I2C %s Address: 0x%02x", i2c_device->name, - i2c_device->client->addr); - - return 0; -} - -static int aml_lcd_extern_i2c_remove(struct i2c_client *client) -{ - kfree(i2c_device); - i2c_set_clientdata(client, NULL); - - return 0; -} - -static const struct i2c_device_id aml_lcd_extern_i2c_id[] = { - {"i2c_DLPC3439", 0}, - {} -}; - -#ifdef CONFIG_OF -static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = { - { - .compatible = "amlogic, lcd_i2c_DLPC3439", - }, - {}, -}; -#endif - -static struct i2c_driver aml_lcd_extern_i2c_driver = { - .probe = aml_lcd_extern_i2c_probe, - .remove = aml_lcd_extern_i2c_remove, - .id_table = aml_lcd_extern_i2c_id, - .driver = { - .name = "i2c_DLPC3439", - .owner = THIS_MODULE, -#ifdef CONFIG_OF - .of_match_table = aml_lcd_extern_i2c_dt_match, -#endif - }, -}; - -module_i2c_driver(aml_lcd_extern_i2c_driver); - -MODULE_AUTHOR("AMLOGIC"); -MODULE_DESCRIPTION("lcd extern driver"); -MODULE_LICENSE("GPL"); - 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 38f8a42..9f86fe7 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c @@ -28,10 +28,14 @@ #include #include "lcd_extern.h" -#define LCD_EXTERN_NAME "i2c_T5800Q" +#define LCD_EXTERN_NAME "i2c_T5800Q" + +#define LCD_EXTERN_I2C_ADDR (0x1c) /* 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 *i2c_device; +static struct aml_lcd_extern_i2c_dev_s *i2c_dev; #define LCD_EXTERN_CMD_SIZE 9 static unsigned char init_on_table[] = { @@ -50,26 +54,6 @@ static unsigned char init_off_table[] = { 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ending */ }; -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_cmd(unsigned char *init_table, int flag) { int i = 0, max_len = 0, step = 0; @@ -110,11 +94,11 @@ static int lcd_extern_power_cmd(unsigned char *init_table, int flag) init_table[i+2]); } } else if (init_table[i] == LCD_EXTERN_INIT_CMD) { - if (i2c_device == NULL) { + if (i2c_dev == NULL) { EXTERR("invalid i2c device\n"); return -1; } - ret = lcd_extern_i2c_write(i2c_device->client, + ret = lcd_extern_i2c_write(i2c_dev->client, &init_table[i+1], (cmd_size-2)); } else { EXTERR("%s(%d: %s): power_type %d is invalid\n", @@ -144,21 +128,21 @@ static int lcd_extern_power_ctrl(int flag) return ret; } -static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_on(void) { int ret; - lcd_extern_pinmux_set(ext_drv, 1); + lcd_extern_pinmux_set(1); ret = lcd_extern_power_ctrl(1); return ret; } -static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_off(void) { int ret; - lcd_extern_pinmux_set(ext_drv, 0); ret = lcd_extern_power_ctrl(0); + lcd_extern_pinmux_set(0); return ret; } @@ -169,9 +153,9 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv) return -1; } - if (ext_drv->config.table_init_loaded == 0) { - ext_drv->config.table_init_on = init_on_table; - ext_drv->config.table_init_off = init_off_table; + if (ext_drv->config->table_init_loaded == 0) { + ext_drv->config->table_init_on = init_on_table; + ext_drv->config->table_init_off = init_off_table; } ext_drv->power_on = lcd_extern_power_on; ext_drv->power_off = lcd_extern_power_off; @@ -183,15 +167,15 @@ int aml_lcd_extern_i2c_T5800Q_probe(struct aml_lcd_extern_driver_s *ext_drv) { int ret = 0; - ext_config = &ext_drv->config; - if (i2c_device == NULL) { + ext_config = ext_drv->config; + + i2c_dev = lcd_extern_get_i2c_device(ext_config->i2c_addr); + if (i2c_dev == NULL) { EXTERR("invalid i2c device\n"); return -1; } - if (ext_drv->config.i2c_addr != i2c_device->client->addr) { - EXTERR("invalid i2c addr\n"); - return -1; - } + EXTPR("get i2c device: %s, addr 0x%02x OK\n", + i2c_dev->name, i2c_dev->client->addr); ret = lcd_extern_driver_update(ext_drv); EXTPR("%s: %d\n", __func__, ret); @@ -200,111 +184,9 @@ int aml_lcd_extern_i2c_T5800Q_probe(struct aml_lcd_extern_driver_s *ext_drv) int aml_lcd_extern_i2c_T5800Q_remove(void) { - return 0; -} - -static int lcd_extern_i2c_config_from_dts(struct device *dev, - struct aml_lcd_extern_i2c_dev_s *i2c_device) -{ - int ret; - struct device_node *np = dev->of_node; - const char *str; - - ret = of_property_read_string(np, "dev_name", &str); - if (ret) { - EXTERR("failed to get dev_i2c_name\n"); - str = "lcd_extern_i2c_T5800Q"; - } - strcpy(i2c_device->name, str); - - return 0; -} - -static int aml_lcd_extern_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - EXTERR("I2C check functionality failed."); - return -ENODEV; - } - - i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s), - GFP_KERNEL); - if (!i2c_device) { - EXTERR("driver malloc error\n"); - return -ENOMEM; - } - - i2c_device->client = client; - lcd_extern_i2c_config_from_dts(&client->dev, i2c_device); - EXTPR("I2C %s Address: 0x%02x", i2c_device->name, - i2c_device->client->addr); - - return 0; -} - -static int aml_lcd_extern_i2c_remove(struct i2c_client *client) -{ - kfree(i2c_device); - //i2c_set_clientdata(client, NULL); + i2c_dev = NULL; + ext_config = NULL; return 0; } -static const struct i2c_device_id aml_lcd_extern_i2c_id[] = { - {"i2c_T5800Q", 0}, - {} -}; - -#ifdef CONFIG_OF -static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = { - { - .compatible = "amlogic, lcd_i2c_T5800Q", - }, - {}, -}; -#endif - -static struct i2c_driver aml_lcd_extern_i2c_driver = { - .probe = aml_lcd_extern_i2c_probe, - .remove = aml_lcd_extern_i2c_remove, - .id_table = aml_lcd_extern_i2c_id, - .driver = { - .name = "i2c_T5800Q", - .owner = THIS_MODULE, -#ifdef CONFIG_OF - .of_match_table = aml_lcd_extern_i2c_dt_match, -#endif - }, -}; - -static int __init aml_lcd_extern_i2c_init(void) -{ - int ret; - - //if (lcd_debug_print_flag) - EXTPR("%s\n", __func__); - - ret = i2c_add_driver(&aml_lcd_extern_i2c_driver); - if (ret) { - EXTERR("driver register failed\n"); - return -ENODEV; - } - return ret; -} - -static void __exit aml_lcd_extern_i2c_exit(void) -{ - i2c_del_driver(&aml_lcd_extern_i2c_driver); -} - - -module_init(aml_lcd_extern_i2c_init); -module_exit(aml_lcd_extern_i2c_exit); - -//module_i2c_driver(aml_lcd_extern_i2c_driver); - -MODULE_AUTHOR("AMLOGIC"); -MODULE_DESCRIPTION("lcd extern driver"); -MODULE_LICENSE("GPL"); - 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 40c6388..64e1f0c3 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_anx6345.c @@ -30,79 +30,16 @@ #include "i2c_anx6345.h" static struct lcd_extern_config_s *ext_config; -static struct i2c_client *aml_anx6345_70_client; -static struct i2c_client *aml_anx6345_72_client; +static struct aml_lcd_extern_i2c_dev_s *i2c0_dev; +static struct aml_lcd_extern_i2c_dev_s *i2c1_dev; -const char *anx_addr_name[2] = {"anx6345_70", "anx6345_72"}; static unsigned int edp_tx_lane = 1; -#define LCD_EXTERN_NAME "lcd_anx6345" +#define LCD_EXTERN_NAME "lcd_anx6345" -static int aml_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("%s: i2c transfer failed [addr 0x%02x]\n", - __func__, i2client->addr); - } - - return ret; -} - -static int aml_i2c_read(struct i2c_client *i2client, unsigned char *buff, - unsigned int len) -{ - int ret = 0; - struct i2c_msg msgs[] = { - { - .addr = i2client->addr, - .flags = 0, - .len = 1, - .buf = buff, - }, - { - .addr = i2client->addr, - .flags = I2C_M_RD, - .len = len, - .buf = buff, - }, - }; - - ret = i2c_transfer(i2client->adapter, msgs, 2); - if (ret < 0) { - EXTERR("%s: i2c transfer failed [addr 0x%02x]\n", - __func__, i2client->addr); - } - - return ret; -} - -#if 0 -static int i2c_reg_read(unsigned char reg, unsigned char *buf) -{ - int ret = 0; - - return ret; -} - -static int i2c_reg_write(unsigned char reg, unsigned char value) -{ - int ret = 0; - - return ret; -} -#endif +#define LCD_EXTERN_I2C_ADDR (0x38) /* 7bit address */ +#define LCD_EXTERN_I2C_ADDR2 (0x39) /* 7bit address */ +#define LCD_EXTERN_I2C_BUS LCD_EXTERN_I2C_BUS_2 static int SP_TX_Write_Reg(unsigned char addr, unsigned char reg, unsigned char data) @@ -114,15 +51,15 @@ static int SP_TX_Write_Reg(unsigned char addr, unsigned char reg, buff[0] = reg; buff[1] = data; if (addr == 0x70) - client = aml_anx6345_70_client; + client = i2c0_dev->client; else if (addr == 0x72) - client = aml_anx6345_72_client; + client = i2c1_dev->client; if (client == NULL) { EXTERR("%s: invalid i2c client\n", __func__); return -1; } - ret = aml_i2c_write(client, buff, 1); + ret = lcd_extern_i2c_write(client, buff, 1); return ret; } @@ -134,15 +71,15 @@ static int SP_TX_Read_Reg(unsigned char addr, unsigned char reg, *data = reg; if (addr == 0x70) - client = aml_anx6345_70_client; + client = i2c0_dev->client; else if (addr == 0x72) - client = aml_anx6345_72_client; + client = i2c1_dev->client; if (client == NULL) { EXTERR("%s: invalid i2c client\n", __func__); return -1; } - ret = aml_i2c_read(client, data, 1); + ret = lcd_extern_i2c_read(client, data, 1); return ret; } @@ -200,7 +137,7 @@ static int SP_TX_AUX_DPCDRead_Bytes(unsigned char addrh, unsigned char addrm, return 0; /* aux ok */ } -static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_on(void) { unsigned int lane_num; unsigned int link_rate; @@ -211,7 +148,8 @@ static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) unsigned int count = 0; unsigned int count1 = 0; - lcd_extern_pinmux_set(ext_drv, 1); + lcd_extern_pinmux_set(1); + lane_num = edp_tx_lane; /* 1 lane */ link_rate = VAL_EDP_TX_LINK_BW_SET_270; /* 2.7G */ bits = 0; /* 0x00: 6bit; 0x10:8bit */ @@ -353,11 +291,11 @@ static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) return 0; } -static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_off(void) { int ret = 0; - lcd_extern_pinmux_set(ext_drv, 0); + lcd_extern_pinmux_set(0); return ret; } @@ -377,131 +315,28 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv) return ret; } -static int aml_anx6345_70_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - EXTERR("%s: functionality check failed\n", __func__); - else - aml_anx6345_70_client = client; - - EXTPR("%s OK\n", __func__); - return 0; -} - -static int aml_anx6345_72_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - EXTERR("%s: functionality check failed\n", __func__); - else - aml_anx6345_72_client = client; - - EXTPR("%s OK\n", __func__); - return 0; -} - -static int aml_anx6345_70_remove(struct i2c_client *client) -{ - return 0; -} -static int aml_anx6345_72_remove(struct i2c_client *client) -{ - return 0; -} - -static const struct i2c_device_id aml_anx6345_70_id[] = { - {"anx6345_70", 0}, - { } -}; -static const struct i2c_device_id aml_anx6345_72_id[] = { - {"anx6345_72", 0}, - { } -}; - -/* MODULE_DEVICE_TABLE(i2c, aml_tc101_id); */ - -static struct i2c_driver aml_anx6345_70_driver = { - .probe = aml_anx6345_70_probe, - .remove = aml_anx6345_70_remove, - .id_table = aml_anx6345_70_id, - .driver = { - .name = "anx6345_70", - .owner = THIS_MODULE, - }, -}; - -static struct i2c_driver aml_anx6345_72_driver = { - .probe = aml_anx6345_72_probe, - .remove = aml_anx6345_72_remove, - .id_table = aml_anx6345_72_id, - .driver = { - .name = "anx6345_72", - .owner = THIS_MODULE, - }, -}; - int aml_lcd_extern_i2c_anx6345_probe(struct aml_lcd_extern_driver_s *ext_drv) { - struct i2c_board_info i2c_info[2]; - struct i2c_adapter *adapter; - struct i2c_client *i2c_client; - int i = 0; int ret = 0; - ext_config = &ext_drv->config; - if (ext_config->i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) { - EXTERR("invalid i2c bus\n"); - return -1; - } - for (i = 0; i < 2; i++) - memset(&i2c_info[i], 0, sizeof(i2c_info[i])); + ext_config = ext_drv->config; - adapter = i2c_get_adapter(ext_config->i2c_bus); - if (!adapter) { - EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name); + 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); - i2c_info[0].addr = 0x38; /* 0x70 >> 1; */ - i2c_info[1].addr = 0x39; /* 0x72 >> 1; */ - for (i = 0; i < 2; i++) { - strncpy(i2c_info[i].type, anx_addr_name[i], I2C_NAME_SIZE); - /* i2c_info[i].platform_data = &ext_drv->config; */ - i2c_info[i].flags = 0; - if (i2c_info[i].addr > 0x7f) { - EXTERR("%s invalid i2c address: 0x%02x\n", - ext_drv->config.name, i2c_info[i].addr); - return -1; - } - i2c_client = i2c_new_device(adapter, &i2c_info[i]); - if (!i2c_client) { - EXTERR("%s failed to new i2c device\n", - ext_drv->config.name); - } else { - if (lcd_debug_print_flag) { - EXTPR("%s new i2c device succeed\n", - ext_drv->config.name); - } - } - } - - if (!aml_anx6345_70_client) { - ret = i2c_add_driver(&aml_anx6345_70_driver); - if (ret) { - EXTERR("%s add i2c_driver failed\n", - ext_drv->config.name); - return -1; - } - } - if (!aml_anx6345_72_client) { - ret = i2c_add_driver(&aml_anx6345_72_driver); - if (ret) { - EXTERR("%s add i2c_driver failed\n", - ext_drv->config.name); - return -1; - } + 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); @@ -510,3 +345,12 @@ int aml_lcd_extern_i2c_anx6345_probe(struct aml_lcd_extern_driver_s *ext_drv) return ret; } +int aml_lcd_extern_i2c_anx6345_remove(void) +{ + i2c0_dev = NULL; + i2c1_dev = NULL; + ext_config = NULL; + + return 0; +} + diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c index 09d7bc7..af8d3a5 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c @@ -28,10 +28,15 @@ #include #include "lcd_extern.h" -#define LCD_EXTERN_NAME "i2c_tc101" +#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 *i2c_device; +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) */ @@ -63,15 +68,15 @@ static int lcd_extern_i2c_write(struct i2c_client *i2client, return ret; } -static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_on(void) { unsigned char tData[4]; int i = 0, ending_flag = 0; int ret = 0; - lcd_extern_pinmux_set(ext_drv, 1); + lcd_extern_pinmux_set(1); - if (i2c_device == NULL) { + if (i2c0_dev == NULL) { EXTERR("invalid i2c device\n"); return -1; } @@ -86,7 +91,7 @@ static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) 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(i2c_device->client, tData, 3); + lcd_extern_i2c_write(i2c0_dev->client, tData, 3); } i++; } @@ -94,11 +99,11 @@ static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) return ret; } -static int lcd_extern_power_off(struct aml_lcd_extern_driver_s *ext_drv) +static int lcd_extern_power_off(void) { int ret = 0; - lcd_extern_pinmux_set(ext_drv, 0); + lcd_extern_pinmux_set(0); return ret; } @@ -121,15 +126,24 @@ int aml_lcd_extern_i2c_tc101_probe(struct aml_lcd_extern_driver_s *ext_drv) { int ret = 0; - ext_config = &ext_drv->config; - if (i2c_device == NULL) { - EXTERR("invalid i2c device\n"); + 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; } - if (ext_drv->config.i2c_addr != i2c_device->client->addr) { - EXTERR("invalid i2c addr\n"); + 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); @@ -138,83 +152,11 @@ int aml_lcd_extern_i2c_tc101_probe(struct aml_lcd_extern_driver_s *ext_drv) return ret; } -static int lcd_extern_i2c_config_from_dts(struct device *dev, - struct aml_lcd_extern_i2c_dev_s *i2c_device) -{ - int ret; - struct device_node *np = dev->of_node; - const char *str; - - ret = of_property_read_string(np, "dev_name", &str); - if (ret) { - EXTERR("failed to get dev_i2c_name\n"); - str = "lcd_extern_i2c_tc101"; - } - strcpy(i2c_device->name, str); - - return 0; -} - -static int aml_lcd_extern_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) -{ - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) { - EXTERR("I2C check functionality failed."); - return -ENODEV; - } - - i2c_device = kzalloc(sizeof(struct aml_lcd_extern_i2c_dev_s), - GFP_KERNEL); - if (!i2c_device) { - EXTERR("driver malloc error\n"); - return -ENOMEM; - } - i2c_device->client = client; - lcd_extern_i2c_config_from_dts(&client->dev, i2c_device); - EXTPR("I2C %s Address: 0x%02x", i2c_device->name, - i2c_device->client->addr); - - return 0; -} - -static int aml_lcd_extern_i2c_remove(struct i2c_client *client) +int aml_lcd_extern_i2c_tc101_remove(void) { - kfree(i2c_device); - i2c_set_clientdata(client, NULL); + i2c0_dev = NULL; + i2c1_dev = NULL; + ext_config = NULL; return 0; } - -static const struct i2c_device_id aml_lcd_extern_i2c_id[] = { - {"i2c_tc101", 0}, - {} -}; - -#ifdef CONFIG_OF -static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = { - { - .compatible = "amlogic, lcd_i2c_tc101", - }, - {}, -}; -#endif - -static struct i2c_driver aml_lcd_extern_i2c_driver = { - .probe = aml_lcd_extern_i2c_probe, - .remove = aml_lcd_extern_i2c_remove, - .id_table = aml_lcd_extern_i2c_id, - .driver = { - .name = "i2c_tc101", - .owner = THIS_MODULE, -#ifdef CONFIG_OF - .of_match_table = aml_lcd_extern_i2c_dt_match, -#endif - }, -}; - -module_i2c_driver(aml_lcd_extern_i2c_driver); - -MODULE_AUTHOR("AMLOGIC"); -MODULE_DESCRIPTION("lcd extern driver"); -MODULE_LICENSE("GPL"); - 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 f5db99d..d6e86c7 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.c @@ -27,20 +27,14 @@ #include #include #include +#include #include "lcd_extern.h" static struct device *lcd_extern_dev; -static int lcd_ext_driver_num; -static struct aml_lcd_extern_driver_s *lcd_ext_driver[LCD_EXT_DRIVER_MAX]; +static struct aml_lcd_extern_driver_s *lcd_ext_driver; static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf); -static unsigned int lcd_ext_key_valid; static unsigned char lcd_ext_config_load; -static unsigned char lcd_ext_i2c_bus = LCD_EXTERN_I2C_BUS_INVALID; -static unsigned char lcd_ext_i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX; -static unsigned char lcd_ext_i2c_sck_gpio_off = 2; -static unsigned char lcd_ext_i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX; -static unsigned char lcd_ext_i2c_sda_gpio_off = 2; struct lcd_ext_gpio_s { char name[15]; @@ -58,44 +52,49 @@ static struct lcd_ext_gpio_s lcd_extern_gpio[LCD_EXTERN_GPIO_NUM_MAX] = { {.probe_flag = 0, .register_flag = 0,}, }; +static struct lcd_extern_config_s lcd_extern_config = { + .index = LCD_EXTERN_INDEX_INVALID, + .name = "invalid", + .type = LCD_EXTERN_MAX, + .status = 0, + .pinmux_valid = 0, + .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_sck_gpio_off = 2, + .i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX, + .i2c_sda_gpio_off = 2, + + .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_clk_freq = 0, + .spi_delay_us = 0, + .spi_clk_pol = 1, + + .cmd_size = 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) { - int i; - struct aml_lcd_extern_driver_s *ext_driver = NULL; - if (index >= LCD_EXTERN_INDEX_INVALID) { EXTERR("invalid driver index: %d\n", index); return NULL; } - for (i = 0; i < lcd_ext_driver_num; i++) { - if (lcd_ext_driver[i]->config.index == index) { - ext_driver = lcd_ext_driver[i]; - break; - } - } - if (ext_driver == NULL) - EXTERR("invalid driver index: %d\n", index); - return ext_driver; -} - -#if 0 -static struct aml_lcd_extern_driver_s - *aml_lcd_extern_get_driver_by_name(char *name) -{ - int i; - struct aml_lcd_extern_driver_s *ext_driver = NULL; + if (lcd_ext_driver->config->index == index) + return lcd_ext_driver; - for (i = 0; i < lcd_ext_driver_num; i++) { - if (strcmp(lcd_ext_driver[i]->config.name, name) == 0) { - ext_driver = lcd_ext_driver[i]; - break; - } - } - if (ext_driver == NULL) - EXTERR("invalid driver name: %s\n", name); - return ext_driver; + EXTERR("invalid driver index: %d\n", index); + return NULL; } -#endif #ifdef CONFIG_OF void lcd_extern_gpio_probe(unsigned char index) @@ -290,71 +289,44 @@ unsigned int lcd_extern_gpio_get(unsigned char index) return gpiod_get_value(ext_gpio->gpio); } -void lcd_extern_pinmux_set(struct aml_lcd_extern_driver_s *ext_drv, int status) +void lcd_extern_pinmux_set(int status) { - struct lcd_ext_gpio_s *ext_gpio_sck; - struct lcd_ext_gpio_s *ext_gpio_sda; + /* kernel4.9 can't release pins */ + if (lcd_ext_driver == NULL) + return; - ext_gpio_sck = &lcd_extern_gpio[ext_drv->config.i2c_sck_gpio]; - ext_gpio_sda = &lcd_extern_gpio[ext_drv->config.i2c_sda_gpio]; + if (lcd_ext_driver->config->pinmux_valid == 0) { + if (lcd_debug_print_flag) { + EXTPR("%s: pinmux_valid %d, bypass\n", + __func__, lcd_ext_driver->config->pinmux_valid); + } + return; + } if (lcd_debug_print_flag) EXTPR("%s: %d\n", __func__, status); if (status) { /* release gpio */ - if (ext_drv->pinmux_flag) { + if (lcd_ext_driver->pinmux_flag) { EXTPR("drv_index %d pinmux is already selected\n", - ext_drv->config.index); + lcd_ext_driver->config->index); return; } - if (ext_drv->config.type == LCD_EXTERN_I2C) { - if (ext_drv->config.i2c_sck_gpio < - LCD_EXTERN_GPIO_NUM_MAX) - lcd_extern_gpio_unregister( - ext_drv->config.i2c_sck_gpio); - if (ext_drv->config.i2c_sda_gpio < - LCD_EXTERN_GPIO_NUM_MAX) - lcd_extern_gpio_unregister( - ext_drv->config.i2c_sda_gpio); - } + /* request pinmux */ - ext_drv->pin = devm_pinctrl_get_select(lcd_extern_dev, + lcd_ext_driver->pin = devm_pinctrl_get_select(lcd_extern_dev, "extern_pins"); - if (IS_ERR(ext_drv->pin)) { + if (IS_ERR(lcd_ext_driver->pin)) { EXTERR("set drv_index %d pinmux error\n", - ext_drv->config.index); + lcd_ext_driver->config->index); } else { if (lcd_debug_print_flag) { EXTPR("set drv_index %d pinmux ok\n", - ext_drv->config.index); - } - } - ext_drv->pinmux_flag = 1; - } else { - if (ext_drv->pinmux_flag) { - if (lcd_debug_print_flag) - EXTPR("release pinmux: %p\n", ext_drv->pin); - /* release pinmux */ - if (!IS_ERR(ext_drv->pin)) - devm_pinctrl_put(ext_drv->pin); - ext_drv->pinmux_flag = 0; - } - /* request gpio & set gpio */ - if (ext_drv->config.type == LCD_EXTERN_I2C) { - if (ext_drv->config.i2c_sck_gpio < - LCD_EXTERN_GPIO_NUM_MAX) { - lcd_extern_gpio_set( - ext_drv->config.i2c_sck_gpio, - ext_drv->config.i2c_sck_gpio_off); - } - if (ext_drv->config.i2c_sda_gpio < - LCD_EXTERN_GPIO_NUM_MAX) { - lcd_extern_gpio_set( - ext_drv->config.i2c_sda_gpio, - ext_drv->config.i2c_sda_gpio_off); + lcd_ext_driver->config->index); } } + lcd_ext_driver->pinmux_flag = 1; } } @@ -364,15 +336,25 @@ 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 = AML_I2C_MASTER_AO; + i2c_bus = LCD_EXTERN_I2C_BUS_4; else if (strncmp(str, "i2c_bus_a", 9) == 0) - i2c_bus = AML_I2C_MASTER_A; + i2c_bus = LCD_EXTERN_I2C_BUS_0; else if (strncmp(str, "i2c_bus_b", 9) == 0) - i2c_bus = AML_I2C_MASTER_B; + i2c_bus = LCD_EXTERN_I2C_BUS_1; else if (strncmp(str, "i2c_bus_c", 9) == 0) - i2c_bus = AML_I2C_MASTER_C; + i2c_bus = LCD_EXTERN_I2C_BUS_2; else if (strncmp(str, "i2c_bus_d", 9) == 0) - i2c_bus = AML_I2C_MASTER_D; + i2c_bus = LCD_EXTERN_I2C_BUS_3; + else if (strncmp(str, "i2c_bus_0", 9) == 0) + i2c_bus = LCD_EXTERN_I2C_BUS_0; + else if (strncmp(str, "i2c_bus_1", 9) == 0) + i2c_bus = LCD_EXTERN_I2C_BUS_1; + else if (strncmp(str, "i2c_bus_2", 9) == 0) + i2c_bus = LCD_EXTERN_I2C_BUS_2; + else if (strncmp(str, "i2c_bus_3", 9) == 0) + i2c_bus = LCD_EXTERN_I2C_BUS_3; + else if (strncmp(str, "i2c_bus_4", 9) == 0) + i2c_bus = LCD_EXTERN_I2C_BUS_4; else { i2c_bus = LCD_EXTERN_I2C_BUS_INVALID; EXTERR("invalid i2c_bus: %s\n", str); @@ -676,10 +658,11 @@ static int lcd_extern_get_config_dts(struct device_node *of_node, ret = of_property_read_string(of_node, "extern_name", &str); if (ret) { - str = "none"; EXTERR("get extern_name failed\n"); + strncpy(extconf->name, "none", LCD_EXTERN_NAME_LEN_MAX); + } else { + strncpy(extconf->name, str, LCD_EXTERN_NAME_LEN_MAX); } - strncpy(extconf->name, str, LCD_EXTERN_NAME_LEN_MAX); /* ensure string ending */ extconf->name[LCD_EXTERN_NAME_LEN_MAX-1] = '\0'; EXTPR("load config: %s[%d]\n", extconf->name, extconf->index); @@ -693,17 +676,8 @@ static int lcd_extern_get_config_dts(struct device_node *of_node, switch (extconf->type) { case LCD_EXTERN_I2C: - if (lcd_ext_i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) { - ret = of_property_read_string(of_node, "i2c_bus", &str); - if (ret) { - EXTERR("get %s i2c_bus failed, exit\n", - extconf->name); - extconf->i2c_bus = LCD_EXTERN_I2C_BUS_INVALID; - return -1; - } - extconf->i2c_bus = lcd_extern_get_i2c_bus_str(str); - } else - extconf->i2c_bus = lcd_ext_i2c_bus; + if (extconf->i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) + EXTERR("get %s i2c_bus failed\n", extconf->name); if (lcd_debug_print_flag) { EXTPR("%s i2c_bus=%d\n", extconf->name, extconf->i2c_bus); @@ -733,17 +707,6 @@ static int lcd_extern_get_config_dts(struct device_node *of_node, extconf->name, extconf->i2c_addr2); } - extconf->i2c_sck_gpio = lcd_ext_i2c_sck_gpio; - extconf->i2c_sck_gpio_off = lcd_ext_i2c_sck_gpio_off; - extconf->i2c_sda_gpio = lcd_ext_i2c_sda_gpio; - extconf->i2c_sda_gpio_off = lcd_ext_i2c_sda_gpio_off; - if ((lcd_ext_i2c_sck_gpio < LCD_EXTERN_GPIO_NUM_MAX) || - (lcd_ext_i2c_sda_gpio < LCD_EXTERN_GPIO_NUM_MAX)) { - EXTPR("find i2c_gpio_off config\n"); - lcd_extern_gpio_probe(extconf->i2c_sck_gpio); - lcd_extern_gpio_probe(extconf->i2c_sda_gpio); - } - ret = of_property_read_u32(of_node, "cmd_size", &val); if (ret) { if (extconf->index == 0) { @@ -921,17 +884,6 @@ static int lcd_extern_get_config_dts(struct device_node *of_node, } #endif - -static unsigned char lcd_extern_get_i2c_bus_unifykey(unsigned char val) -{ - if (lcd_ext_i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) - EXTERR("get i2c_bus failed\n"); - if (lcd_debug_print_flag) - EXTPR("i2c_bus=%d\n", lcd_ext_i2c_bus); - - return lcd_ext_i2c_bus; -} - static int lcd_extern_init_table_dynamic_size_load_unifykey( struct lcd_extern_config_s *extconf, unsigned char *p, int key_len, int len, int flag) @@ -1273,18 +1225,10 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf) case LCD_EXTERN_I2C: extconf->i2c_addr = *(p + LCD_UKEY_EXT_TYPE_VAL_0); extconf->i2c_addr2 = *(p + LCD_UKEY_EXT_TYPE_VAL_1); - extconf->i2c_bus = lcd_extern_get_i2c_bus_unifykey( - *(p + LCD_UKEY_EXT_TYPE_VAL_2)); - extconf->i2c_sck_gpio = lcd_ext_i2c_sck_gpio; - extconf->i2c_sck_gpio_off = lcd_ext_i2c_sck_gpio_off; - extconf->i2c_sda_gpio = lcd_ext_i2c_sda_gpio; - extconf->i2c_sda_gpio_off = lcd_ext_i2c_sda_gpio_off; - if ((lcd_ext_i2c_sck_gpio < LCD_EXTERN_GPIO_NUM_MAX) || - (lcd_ext_i2c_sda_gpio < LCD_EXTERN_GPIO_NUM_MAX)) { - EXTPR("find i2c_gpio_off config\n"); - lcd_extern_gpio_probe(extconf->i2c_sck_gpio); - lcd_extern_gpio_probe(extconf->i2c_sda_gpio); - } + /*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); + extconf->cmd_size = *(p + LCD_UKEY_EXT_TYPE_VAL_3); /* init */ @@ -1377,9 +1321,8 @@ static int lcd_extern_get_config_unifykey(struct lcd_extern_config_s *extconf) static int lcd_extern_get_config(void) { struct device_node *child; - struct lcd_extern_config_s extconf; - unsigned char *lcd_ext_init_on_table; - unsigned char *lcd_ext_init_off_table; + unsigned int ext_index = LCD_EXTERN_INDEX_INVALID; + char ext_propname[20]; unsigned int extern_para[5]; const char *str; int load_id = 0; @@ -1390,86 +1333,100 @@ static int lcd_extern_get_config(void) return -1; } - lcd_ext_init_on_table = - kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX, + lcd_extern_config.table_init_on = + kzalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX, GFP_KERNEL); - if (lcd_ext_init_on_table == NULL) { + if (lcd_extern_config.table_init_on == NULL) { EXTERR("failed to alloc default init table\n"); return -1; } - lcd_ext_init_off_table = - kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX, + lcd_extern_config.table_init_off = + kzalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX, GFP_KERNEL); - if (lcd_ext_init_off_table == NULL) { + if (lcd_extern_config.table_init_off == NULL) { EXTERR("failed to alloc default init table\n"); - kfree(lcd_ext_init_on_table); + kfree(lcd_extern_config.table_init_on); return -1; } - lcd_ext_init_on_table[0] = LCD_EXTERN_INIT_END; - lcd_ext_init_off_table[0] = LCD_EXTERN_INIT_END; + 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); + ret = of_property_read_string(lcd_extern_dev->of_node, "i2c_bus", &str); if (ret) - lcd_ext_i2c_bus = LCD_EXTERN_I2C_BUS_INVALID; + lcd_extern_config.i2c_bus = LCD_EXTERN_I2C_BUS_INVALID; else - lcd_ext_i2c_bus = lcd_extern_get_i2c_bus_str(str); - if (lcd_debug_print_flag) - EXTPR("i2c_bus=%s[%d]\n", str, lcd_ext_i2c_bus); + 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_off", &extern_para[0], 4); + "i2c_gpio_off", &extern_para[0], 4); if (ret) { - lcd_ext_i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX; - lcd_ext_i2c_sck_gpio_off = 2; - lcd_ext_i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX; - lcd_ext_i2c_sda_gpio_off = 2; + lcd_extern_config.i2c_sck_gpio = LCD_EXTERN_GPIO_NUM_MAX; + lcd_extern_config.i2c_sck_gpio_off = 2; + lcd_extern_config.i2c_sda_gpio = LCD_EXTERN_GPIO_NUM_MAX; + lcd_extern_config.i2c_sda_gpio_off = 2; } else { - lcd_ext_i2c_sck_gpio = extern_para[0]; - lcd_ext_i2c_sck_gpio_off = extern_para[1]; - lcd_ext_i2c_sda_gpio = extern_para[2]; - lcd_ext_i2c_sda_gpio_off = extern_para[3]; + lcd_extern_config.i2c_sck_gpio = (unsigned char)extern_para[0]; + lcd_extern_config.i2c_sck_gpio_off = + (unsigned char) extern_para[1]; + lcd_extern_config.i2c_sda_gpio = (unsigned char)extern_para[2]; + lcd_extern_config.i2c_sda_gpio_off = + (unsigned char)extern_para[3]; } + ret = of_property_read_string(lcd_extern_dev->of_node, + "pinctrl-names", &str); + if (ret) + lcd_extern_config.pinmux_valid = 0; + else + lcd_extern_config.pinmux_valid = 1; + ret = of_property_read_u32(lcd_extern_dev->of_node, - "key_valid", &lcd_ext_key_valid); + "key_valid", &extern_para[0]); if (ret) { if (lcd_debug_print_flag) EXTPR("failed to get key_valid\n"); - lcd_ext_key_valid = 0; + lcd_extern_config.key_valid = 0; + } else { + lcd_extern_config.key_valid = (unsigned char)extern_para[0]; } - EXTPR("key_valid: %d\n", lcd_ext_key_valid); + EXTPR("key_valid: %d\n", lcd_extern_config.key_valid); - if (lcd_ext_key_valid) { + if (lcd_extern_config.key_valid) { ret = lcd_unifykey_check("lcd_extern"); if (ret < 0) load_id = 0; else load_id = 1; } - memset(&extconf, 0, sizeof(struct lcd_extern_config_s)); - extconf.table_init_on = lcd_ext_init_on_table; - extconf.table_init_off = lcd_ext_init_off_table; + if (load_id) { EXTPR("%s from unifykey\n", __func__); lcd_ext_config_load = 1; - ret = lcd_extern_get_config_unifykey(&extconf); + ret = lcd_extern_get_config_unifykey(&lcd_extern_config); if (ret == 0) - lcd_extern_add_driver(&extconf); + lcd_extern_add_driver(&lcd_extern_config); } else { #ifdef CONFIG_OF - EXTPR("%s from dts\n", __func__); + 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); lcd_ext_config_load = 0; - for_each_child_of_node(lcd_extern_dev->of_node, child) { - ret = lcd_extern_get_config_dts(child, &extconf); - if (ret == 0) - lcd_extern_add_driver(&extconf); + 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); #endif } - kfree(lcd_ext_init_on_table); - kfree(lcd_ext_init_off_table); return 0; } @@ -1477,28 +1434,26 @@ static int lcd_extern_add_i2c(struct aml_lcd_extern_driver_s *ext_drv) { int ret = 0; - if (strcmp(ext_drv->config.name, "ext_default") == 0) { -#ifdef LCD_EXTERN_DEFAULT_ENABLE + if (strcmp(ext_drv->config->name, "ext_default") == 0) { ret = aml_lcd_extern_default_probe(ext_drv); -#endif - } else if (strcmp(ext_drv->config.name, "i2c_T5800Q") == 0) { + } 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); #endif - } else if (strcmp(ext_drv->config.name, "i2c_tc101") == 0) { + } else if (strcmp(ext_drv->config->name, "i2c_tc101") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_TC101 ret = aml_lcd_extern_i2c_tc101_probe(ext_drv); #endif - } else if (strcmp(ext_drv->config.name, "i2c_anx6345") == 0) { + } else if (strcmp(ext_drv->config->name, "i2c_anx6345") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_ANX6345 ret = aml_lcd_extern_i2c_anx6345_probe(ext_drv); #endif - } else if (strcmp(ext_drv->config.name, "i2c_DLPC3439") == 0) { + } else if (strcmp(ext_drv->config->name, "i2c_DLPC3439") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_DLPC3439 ret = aml_lcd_extern_i2c_DLPC3439_probe(ext_drv); #endif } else { - EXTERR("invalid driver name: %s\n", ext_drv->config.name); + EXTERR("invalid driver name: %s\n", ext_drv->config->name); ret = -1; } return ret; @@ -1508,16 +1463,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) { -#ifdef LCD_EXTERN_DEFAULT_ENABLE + if (strcmp(ext_drv->config->name, "ext_default") == 0) { ret = aml_lcd_extern_default_probe(ext_drv); -#endif - } else if (strcmp(ext_drv->config.name, "spi_LD070WS2") == 0) { + } 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); #endif } else { - EXTERR("invalid driver name: %s\n", ext_drv->config.name); + EXTERR("invalid driver name: %s\n", ext_drv->config->name); ret = -1; } return ret; @@ -1527,34 +1480,34 @@ 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) { + if (strcmp(ext_drv->config->name, "mipi_default") == 0) { ret = aml_lcd_extern_mipi_default_probe(ext_drv); - } else if (strcmp(ext_drv->config.name, "mipi_N070ICN") == 0) { + } 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); #endif - } else if (strcmp(ext_drv->config.name, "mipi_KD080D13") == 0) { + } else if (strcmp(ext_drv->config->name, "mipi_KD080D13") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_KD080D13 ret = aml_lcd_extern_mipi_KD080D13_probe(ext_drv); #endif - } else if (strcmp(ext_drv->config.name, "mipi_TV070WSM") == 0) { + } else if (strcmp(ext_drv->config->name, "mipi_TV070WSM") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_TV070WSM ret = aml_lcd_extern_mipi_TV070WSM_probe(ext_drv); #endif - } else if (strcmp(ext_drv->config.name, "mipi_ST7701") == 0) { + } else if (strcmp(ext_drv->config->name, "mipi_ST7701") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_ST7701 ret = aml_lcd_extern_mipi_st7701_probe(ext_drv); #endif - } else if (strcmp(ext_drv->config.name, "mipi_P070ACB") == 0) { + } else if (strcmp(ext_drv->config->name, "mipi_P070ACB") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_P070ACB ret = aml_lcd_extern_mipi_p070acb_probe(ext_drv); #endif - } else if (strcmp(ext_drv->config.name, "mipi_TL050FHV02CT") == 0) { + } else if (strcmp(ext_drv->config->name, "mipi_TL050FHV02CT") == 0) { #ifdef CONFIG_AMLOGIC_LCD_EXTERN_MIPI_TL050FHV02CT ret = aml_lcd_extern_mipi_tl050fhv02ct_probe(ext_drv); #endif } else { - EXTERR("invalid driver name: %s\n", ext_drv->config.name); + EXTERR("invalid driver name: %s\n", ext_drv->config->name); ret = -1; } return ret; @@ -1568,80 +1521,31 @@ static int lcd_extern_add_invalid(struct aml_lcd_extern_driver_s *ext_drv) static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf) { struct aml_lcd_extern_driver_s *ext_drv; - int i; int ret = 0; - if (lcd_ext_driver_num >= LCD_EXT_DRIVER_MAX) { - EXTERR("driver num is out of support\n"); - return -1; - } if (extconf->status == 0) { EXTERR("driver %s[%d] status is disabled\n", extconf->name, extconf->index); return -1; } - i = lcd_ext_driver_num; - lcd_ext_driver[i] = - kmalloc(sizeof(struct aml_lcd_extern_driver_s), GFP_KERNEL); - if (lcd_ext_driver[i] == NULL) { + lcd_ext_driver = + kzalloc(sizeof(struct aml_lcd_extern_driver_s), GFP_KERNEL); + if (lcd_ext_driver == NULL) { EXTERR("failed to alloc driver %s[%d], not enough memory\n", extconf->name, extconf->index); return -1; } - lcd_ext_driver[i]->pinmux_flag = 0; - ext_drv = lcd_ext_driver[i]; - /* fill config parameters */ - ext_drv->config.index = extconf->index; - strcpy(ext_drv->config.name, extconf->name); - ext_drv->config.type = extconf->type; - ext_drv->config.status = extconf->status; - ext_drv->config.cmd_size = extconf->cmd_size; - ext_drv->config.table_init_on = NULL; - ext_drv->config.table_init_off = NULL; - ext_drv->config.table_init_loaded = extconf->table_init_loaded; - ext_drv->config.table_init_on_cnt = extconf->table_init_on_cnt; - if (ext_drv->config.table_init_loaded) { - ext_drv->config.table_init_on = - kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_ON_MAX, - GFP_KERNEL); - if (ext_drv->config.table_init_on == NULL) { - EXTERR("failed to alloc driver %s[%d] init table\n", - extconf->name, extconf->index); - return -1; - } - ext_drv->config.table_init_off = - kmalloc(sizeof(unsigned char) * LCD_EXTERN_INIT_OFF_MAX, - GFP_KERNEL); - if (ext_drv->config.table_init_off == NULL) { - EXTERR("failed to alloc driver %s[%d] init table\n", - extconf->name, extconf->index); - return -1; - } - memcpy(ext_drv->config.table_init_on, extconf->table_init_on, - LCD_EXTERN_INIT_ON_MAX); - memcpy(ext_drv->config.table_init_off, extconf->table_init_off, - LCD_EXTERN_INIT_OFF_MAX); - } + ext_drv = lcd_ext_driver; - /* fill config parameters by different type */ - switch (ext_drv->config.type) { + ext_drv->config = extconf; + ext_drv->pinmux_flag = 0; + + switch (ext_drv->config->type) { case LCD_EXTERN_I2C: - ext_drv->config.i2c_addr = extconf->i2c_addr; - ext_drv->config.i2c_addr2 = extconf->i2c_addr2; - ext_drv->config.i2c_bus = extconf->i2c_bus; - ext_drv->config.i2c_sck_gpio = extconf->i2c_sck_gpio; - ext_drv->config.i2c_sck_gpio_off = extconf->i2c_sck_gpio_off; - ext_drv->config.i2c_sda_gpio = extconf->i2c_sda_gpio; - ext_drv->config.i2c_sda_gpio_off = extconf->i2c_sda_gpio_off; ret = lcd_extern_add_i2c(ext_drv); break; case LCD_EXTERN_SPI: - ext_drv->config.spi_gpio_cs = extconf->spi_gpio_cs; - ext_drv->config.spi_gpio_clk = extconf->spi_gpio_clk; - ext_drv->config.spi_gpio_data = extconf->spi_gpio_data; - ext_drv->config.spi_clk_freq = extconf->spi_clk_freq; - ext_drv->config.spi_clk_pol = extconf->spi_clk_pol; ret = lcd_extern_add_spi(ext_drv); break; case LCD_EXTERN_MIPI: @@ -1649,20 +1553,22 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf) break; default: ret = lcd_extern_add_invalid(ext_drv); - EXTERR("don't support type %d\n", ext_drv->config.type); + EXTERR("don't support type %d\n", ext_drv->config->type); break; } if (ret) { EXTERR("add driver failed\n"); - kfree(lcd_ext_driver[i]->config.table_init_on); - kfree(lcd_ext_driver[i]->config.table_init_off); - kfree(lcd_ext_driver[i]); - lcd_ext_driver[i] = NULL; + kfree(lcd_ext_driver->config->table_init_on); + kfree(lcd_ext_driver->config->table_init_off); + lcd_ext_driver->config->table_init_on = NULL; + lcd_ext_driver->config->table_init_off = NULL; + kfree(lcd_ext_driver); + lcd_ext_driver = NULL; return -1; } - lcd_ext_driver_num++; + EXTPR("add driver %s(%d)\n", - ext_drv->config.name, ext_drv->config.index); + ext_drv->config->name, ext_drv->config->index); return 0; } @@ -1670,7 +1576,7 @@ static int lcd_extern_add_driver(struct lcd_extern_config_s *extconf) * debug function * ********************************************************* */ -#define EXT_LEN_MAX 2000 +#define EXT_LEN_MAX 300 static void lcd_extern_init_table_dynamic_size_print( struct lcd_extern_config_s *econf, int flag) { @@ -1679,7 +1585,7 @@ static void lcd_extern_init_table_dynamic_size_print( char *str; unsigned char *init_table; - str = kmalloc(EXT_LEN_MAX*sizeof(char), GFP_KERNEL); + str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL); if (str == NULL) { EXTERR("lcd_extern_dynamic_size str malloc error\n"); return; @@ -1714,11 +1620,13 @@ static void lcd_extern_init_table_dynamic_size_print( k = snprintf(str, EXT_LEN_MAX, " 0x%02x,%d,", init_table[i], cmd_size); if (cmd_size > 0) { - for (j = 0; j < cmd_size; j++) { + for (j = 0; j < (cmd_size - 1); j++) { k += snprintf(str+k, EXT_LEN_MAX, "0x%02x,", init_table[i+2+j]); } + snprintf(str+k, EXT_LEN_MAX, + "%d,", init_table[i+cmd_size+1]); } pr_info("%s\n", str); i += (cmd_size + 2); @@ -1776,7 +1684,7 @@ static void lcd_extern_init_table_fixed_size_print( char *str; unsigned char *init_table; - str = kmalloc(EXT_LEN_MAX*sizeof(char), GFP_KERNEL); + str = kcalloc(EXT_LEN_MAX, sizeof(char), GFP_KERNEL); if (str == NULL) { EXTERR("lcd_extern_fixed_size str malloc error\n"); return; @@ -1800,10 +1708,12 @@ static void lcd_extern_init_table_fixed_size_print( i = 0; while (i < max_len) { k = snprintf(str, EXT_LEN_MAX, " "); - for (j = 0; j < cmd_size; j++) { + for (j = 0; j < (cmd_size - 1); j++) { k += snprintf(str+k, EXT_LEN_MAX, " 0x%02x", init_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) @@ -1813,15 +1723,16 @@ static void lcd_extern_init_table_fixed_size_print( kfree(str); } -static void lcd_extern_config_dump(struct aml_lcd_extern_driver_s *ext_drv) +static ssize_t lcd_extern_info_show(struct class *class, + struct class_attribute *attr, char *buf) { struct lcd_extern_config_s *econf; - if (ext_drv == NULL) - return; + if (lcd_ext_driver == NULL) + return sprintf(buf, "lcd extern driver is NULL\n"); - econf = &ext_drv->config; - EXTPR("driver %s(%d) info:\n", econf->name, econf->index); + 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); switch (econf->type) { case LCD_EXTERN_I2C: @@ -1880,93 +1791,127 @@ static void lcd_extern_config_dump(struct aml_lcd_extern_driver_s *ext_drv) pr_info("not support extern_type\n"); break; } - pr_info("\n"); -} - -static const char *lcd_extern_debug_usage_str = { -"Usage:\n" -" echo index > info ; dump specified index driver config\n" -" echo all > info ; dump all driver config\n" -}; -static ssize_t lcd_extern_debug_help(struct class *class, - struct class_attribute *attr, char *buf) -{ - return sprintf(buf, "%s\n", lcd_extern_debug_usage_str); + return sprintf(buf, "\n"); } -static ssize_t lcd_extern_info_dump(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) -{ - unsigned int ret = 0; - int i, index; - struct aml_lcd_extern_driver_s *ext_drv; - - index = LCD_EXTERN_INDEX_INVALID; - switch (buf[0]) { - case 'i': - ret = sscanf(buf, "index %d", &index); - if (ret == 1) { - ext_drv = aml_lcd_extern_get_driver(index); - lcd_extern_config_dump(ext_drv); - } else { - EXTERR("invalid parameters\n"); - } - break; - case 'a': - for (i = 0; i < lcd_ext_driver_num; i++) - lcd_extern_config_dump(lcd_ext_driver[i]); - break; - default: - EXTERR("invalid command\n"); - break; - } - - return count; -} - -static ssize_t lcd_extern_debug_key_valid_show(struct class *class, +static ssize_t lcd_extern_key_valid_show(struct class *class, struct class_attribute *attr, char *buf) { - return sprintf(buf, "%d\n", lcd_ext_key_valid); + return sprintf(buf, "%d\n", lcd_extern_config.key_valid); } -static ssize_t lcd_extern_debug_config_load_show(struct class *class, +static ssize_t lcd_extern_config_load_show(struct class *class, struct class_attribute *attr, char *buf) { return sprintf(buf, "%d\n", lcd_ext_config_load); } -static const char *lcd_extern_debug_test_usage_str = { +static const char *lcd_extern_debug_usage_str = { "Usage:\n" -" echo > test ; test power on/off for index extern device\n" +" echo test > debug ; test power on/off for extern device\n" " : 1 for power on, 0 for power off\n" +" echo r > debug ; read reg for extern device\n" +" echo d > debug ; dump regs for extern device\n" +" echo w > debug ; write reg for extern device\n" }; -static ssize_t lcd_extern_debug_test_show(struct class *class, +static ssize_t lcd_extern_debug_show(struct class *class, struct class_attribute *attr, char *buf) { - return sprintf(buf, "%s\n", lcd_extern_debug_test_usage_str); + return sprintf(buf, "%s\n", lcd_extern_debug_usage_str); } -static ssize_t lcd_extern_debug_test_store(struct class *class, +static ssize_t lcd_extern_debug_store(struct class *class, struct class_attribute *attr, const char *buf, size_t count) { unsigned int ret; - int index, flag = 0; - struct aml_lcd_extern_driver_s *ext_drv; + unsigned int val[3], i; + unsigned char reg, value; - index = LCD_EXTERN_INDEX_INVALID; - ret = sscanf(buf, "%d %d", &index, &flag); - ext_drv = aml_lcd_extern_get_driver(index); - if (ext_drv) { - if (flag) { - if (ext_drv->power_on) - ext_drv->power_on(ext_drv); + if (lcd_ext_driver == NULL) { + pr_info("lcd_extern_driver is null\n"); + return count; + } + + switch (buf[0]) { + case 't': + ret = sscanf(buf, "test %d", &val[0]); + if (ret == 1) { + if (val[0]) { + if (lcd_ext_driver->power_on) + lcd_ext_driver->power_on(); + } else { + if (lcd_ext_driver->power_off) + lcd_ext_driver->power_off(); + } + } else { + pr_info("invalid data\n"); + return -EINVAL; + } + break; + case 'r': + ret = sscanf(buf, "r %d %x", &val[0], &val[1]); + if (ret == 2) { + lcd_ext_driver->config->addr_sel = + (unsigned char)val[0]; + reg = (unsigned char)val[1]; + if (lcd_ext_driver->reg_read) { + lcd_ext_driver->reg_read(reg, &value); + pr_info("reg read: 0x%02x = 0x%02x\n", + reg, value); + } } else { - if (ext_drv->power_off) - ext_drv->power_off(ext_drv); + pr_info("invalid data\n"); + return -EINVAL; } + break; + case 'd': + ret = sscanf(buf, "d %d %x %d", &val[0], &val[1], &val[2]); + if (ret == 3) { + lcd_ext_driver->config->addr_sel = + (unsigned char)val[0]; + reg = (unsigned char)val[1]; + if (lcd_ext_driver->reg_read) { + pr_info("reg dump:\n"); + for (i = 0; i < val[2]; i++) { + lcd_ext_driver->reg_read(reg+i, &value); + pr_info(" 0x%02x = 0x%02x\n", + reg, value); + } + } + } else { + pr_info("invalid data\n"); + return -EINVAL; + } + break; + case 'w': + ret = sscanf(buf, "w %d %x %x", &val[0], &val[1], &val[2]); + if (ret == 2) { + lcd_ext_driver->config->addr_sel = + (unsigned char)val[0]; + reg = (unsigned char)val[1]; + value = (unsigned char)val[2]; + if (lcd_ext_driver->reg_write) { + lcd_ext_driver->reg_write(reg, value); + if (lcd_ext_driver->reg_read) { + lcd_ext_driver->reg_read(reg, &value); + pr_info( + "reg write 0x%02x = 0x%02x, readback: 0x%02x\n", + reg, val[2], value); + } else { + pr_info("reg write 0x%02x = 0x%02x\n", + reg, value); + } + } + } else { + pr_info("invalid data\n"); + return -EINVAL; + } + break; + default: + pr_info("invalid data\n"); + break; } return count; @@ -1974,13 +1919,13 @@ static ssize_t lcd_extern_debug_test_store(struct class *class, static struct class_attribute lcd_extern_class_attrs[] = { __ATTR(info, 0644, - lcd_extern_debug_help, lcd_extern_info_dump), + lcd_extern_info_show, NULL), __ATTR(key_valid, 0444, - lcd_extern_debug_key_valid_show, NULL), + lcd_extern_key_valid_show, NULL), __ATTR(config_load, 0444, - lcd_extern_debug_config_load_show, NULL), - __ATTR(test, 0644, - lcd_extern_debug_test_show, lcd_extern_debug_test_store), + lcd_extern_config_load_show, NULL), + __ATTR(debug, 0644, + lcd_extern_debug_show, lcd_extern_debug_store), }; static struct class *debug_class; @@ -2022,7 +1967,7 @@ static int remove_lcd_extern_class(void) static int aml_lcd_extern_probe(struct platform_device *pdev) { lcd_extern_dev = &pdev->dev; - lcd_ext_driver_num = 0; + lcd_extern_get_config(); /* also add ext_driver */ creat_lcd_extern_class(); @@ -2033,15 +1978,13 @@ static int aml_lcd_extern_probe(struct platform_device *pdev) static int aml_lcd_extern_remove(struct platform_device *pdev) { - int i; - remove_lcd_extern_class(); - for (i = 0; i < lcd_ext_driver_num; i++) { - kfree(lcd_ext_driver[i]->config.table_init_on); - kfree(lcd_ext_driver[i]->config.table_init_off); - kfree(lcd_ext_driver[i]); - lcd_ext_driver[i] = NULL; - } + kfree(lcd_ext_driver->config->table_init_on); + kfree(lcd_ext_driver->config->table_init_off); + lcd_ext_driver->config->table_init_on = NULL; + lcd_ext_driver->config->table_init_off = NULL; + kfree(lcd_ext_driver); + lcd_ext_driver = NULL; return 0; } diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts b/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts deleted file mode 100644 index 209b51a..0000000 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts +++ /dev/null @@ -1,99 +0,0 @@ -/* - * drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.dts - * - * 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. - * - */ - -lcd_extern{ - compatible = "amlogic, lcd_extern"; - dev_name = "lcd_extern"; - status = "okay"; - - extern-gpios = <&gpio GPIODV_1 GPIO_ACTIVE_HIGH - &gpio GPIODV_16 GPIO_ACTIVE_HIGH - &gpio GPIODV_17 GPIO_ACTIVE_HIGH>; - extern_gpio_names = "GPIODV_1","GPIODV_16","GPIODV_17"; - - extern_0{ - index = <0>; - extern_name = "i2c_T5800Q"; - status = "disabled"; - - type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */ - i2c_address = <0x1c>; /** 7bit i2c address */ - i2c_bus = "i2c_bus_d"; - }; - - extern_1{ - index = <1>; - extern_name = "i2c_tc101"; - status = "disabled"; - - type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */ - i2c_address = <0x7e>; /** 7bit i2c address */ - i2c_bus = "i2c_bus_a"; - }; - - extern_2{ - index = <2>; - extern_name = "i2c_anx6345"; - status = "disabled"; - - type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */ - i2c_address = <0x38>; /** 7bit i2c address */ - i2c_bus = "i2c_bus_b"; - lane_num = <1>; /** edp lane_num: 1/2/4 */ - bits = <0>; /** lcd_bits(0=6bit, 1=8bit) */ - link_rate = <1>; /** edp link rate: (0=1.62G, 1=27G, 2=5.4G) */ - }; - - extern_3{ - index = <3>; - extern_name = "spi_LD070WS2"; - status = "disabled"; - - type = <1>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */ - - gpio_spi_cs = <0>; /* index in extern-gpios */ - gpio_spi_clk = <1>; /* index in extern-gpios */ - gpio_spi_data = <2>; /* index in extern-gpios */ - }; - - extern_4{ - index = <4>; - extern_name = "mipi_N070ICN"; - status = "disabled"; - - type = <2>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */ - }; - - extern_5{ - index = <5>; - extern_name = "mipi_KD080D13"; - status = "disabled"; - - type = <2>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */ - }; - - extern_6{ - index = <6>; - extern_name = "i2c_DLPC3439"; - status = "disabled"; - - type = <0>; /** lcd_extern_driver type: 0=i2c, 1=spi, 2=mipi */ - i2c_address = <0x1b>; /** 7bit i2c address */ - i2c_bus = "i2c_bus_a"; - }; -}; - 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 e7c5672..9fd9212 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/lcd_extern.h @@ -34,15 +34,23 @@ extern struct device_node *aml_lcd_extern_get_dts_child(int index); extern void lcd_extern_gpio_probe(unsigned char index); extern void lcd_extern_gpio_set(unsigned char index, int value); extern unsigned int lcd_extern_gpio_get(unsigned char index); -extern void lcd_extern_pinmux_set( - struct aml_lcd_extern_driver_s *ext_drv, int status); +extern void lcd_extern_pinmux_set(int status); -#define LCD_EXTERN_DEFAULT_ENABLE +/* common API */ +extern struct aml_lcd_extern_i2c_dev_s *lcd_extern_get_i2c_device( + unsigned char addr); +extern int lcd_extern_i2c_write(struct i2c_client *i2client, + unsigned char *buff, unsigned int len); +extern int lcd_extern_i2c_read(struct i2c_client *i2client, + unsigned char *buff, unsigned int len); -#ifdef LCD_EXTERN_DEFAULT_ENABLE + +/* specific API */ extern int aml_lcd_extern_default_probe( struct aml_lcd_extern_driver_s *ext_drv); -#endif +extern int aml_lcd_extern_mipi_default_probe( + struct aml_lcd_extern_driver_s *ext_drv); + #ifdef CONFIG_AMLOGIC_LCD_EXTERN_I2C_T5800Q extern int aml_lcd_extern_i2c_T5800Q_probe( struct aml_lcd_extern_driver_s *ext_drv); @@ -87,8 +95,6 @@ extern int aml_lcd_extern_mipi_p070acb_probe( extern int aml_lcd_extern_mipi_tl050fhv02ct_probe( struct aml_lcd_extern_driver_s *ext_drv); #endif -extern int aml_lcd_extern_mipi_default_probe( - struct aml_lcd_extern_driver_s *ext_drv); #endif 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 80b15c2..36cab44 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_KD080D13.c @@ -106,8 +106,8 @@ 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]; + ext_drv->config->table_init_on = &mipi_init_on_table[0]; + ext_drv->config->table_init_off = &mipi_init_off_table[0]; } else { EXTERR("%s driver is null\n", LCD_EXTERN_NAME); ret = -1; 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 1e7111a..7bb0e75 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_N070ICN.c @@ -223,8 +223,8 @@ 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]; + ext_drv->config->table_init_on = &mipi_init_on_table[0]; + ext_drv->config->table_init_off = &mipi_init_off_table[0]; } else { EXTERR("%s driver is null\n", LCD_EXTERN_NAME); ret = -1; 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 2c6b020..ed09e4d 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_P070ACB.c @@ -212,8 +212,8 @@ 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]; + ext_drv->config->table_init_on = &mipi_init_on_table[0]; + ext_drv->config->table_init_off = &mipi_init_off_table[0]; } else { EXTERR("%s driver is null\n", LCD_EXTERN_NAME); ret = -1; 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 e1597d7..e2e8f0c3 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_ST7701.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_ST7701.c @@ -111,8 +111,8 @@ 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]; + ext_drv->config->table_init_on = &mipi_init_on_table[0]; + ext_drv->config->table_init_off = &mipi_init_off_table[0]; } else { EXTERR("%s driver is null\n", LCD_EXTERN_NAME); ret = -1; 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 3cf4f5d..457c6fc 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TL050FHV02CT.c @@ -153,8 +153,8 @@ 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]; + ext_drv->config->table_init_on = &mipi_init_on_table[0]; + ext_drv->config->table_init_off = &mipi_init_off_table[0]; } else { EXTERR("%s driver is null\n", LCD_EXTERN_NAME); ret = -1; 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 5559209..903a36b 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TV070WSM.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_TV070WSM.c @@ -174,8 +174,8 @@ 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]; + ext_drv->config->table_init_on = &mipi_init_on_table[0]; + ext_drv->config->table_init_off = &mipi_init_off_table[0]; } else { EXTERR("%s driver is null\n", LCD_EXTERN_NAME); ret = -1; 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 32e339e..6060897 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_default.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/mipi_default.c @@ -57,13 +57,13 @@ 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); + 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]; - ext_drv->config.table_init_off = &mipi_init_off_table[0]; + ext_drv->config->table_init_on = &mipi_init_on_table[0]; + ext_drv->config->table_init_off = &mipi_init_off_table[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 768a402..a0d025a 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/spi_LD070WS2.c @@ -36,7 +36,12 @@ static struct lcd_extern_config_s *ext_config; #define LCD_EXTERN_NAME "lcd_spi_LD070WS2" -#define SPI_DELAY 30 /* unit: us */ +#define SPI_DELAY 30 /* unit: us */ +#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_POL 1 #define LCD_EXTERN_CMD_SIZE 4 static unsigned char init_on_table[] = { @@ -228,11 +233,11 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv) return -1; } - if (ext_drv->config.table_init_loaded == 0) { - ext_drv->config.table_init_on = init_on_table; - ext_drv->config.table_init_off = init_off_table; + if (ext_drv->config->table_init_loaded == 0) { + ext_drv->config->table_init_on = init_on_table; + ext_drv->config->table_init_off = init_off_table; } - ext_drv->config.spi_delay_us = SPI_DELAY; + ext_drv->config->spi_delay_us = SPI_DELAY; ext_drv->power_on = lcd_extern_power_on; ext_drv->power_off = lcd_extern_power_off; @@ -244,10 +249,17 @@ int aml_lcd_extern_spi_LD070WS2_probe(struct aml_lcd_extern_driver_s *ext_drv) { int ret = 0; - ext_config = &ext_drv->config; + ext_config = ext_drv->config; ret = lcd_extern_driver_update(ext_drv); if (lcd_debug_print_flag) EXTPR("%s: %d\n", __func__, ret); return ret; } + +int aml_lcd_extern_spi_LD070WS2_remove(void) +{ + ext_config = NULL; + + return 0; +} 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 81bee22..1a73779 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 @@ -1916,10 +1916,10 @@ static void mipi_dsi_link_on(struct lcd_config_s *pconf) if (lcd_ext == NULL) { LCDPR("no lcd_extern driver\n"); } else { - if (lcd_ext->config.table_init_on) { - dsi_write_cmd(lcd_ext->config.table_init_on); + if (lcd_ext->config->table_init_on) { + dsi_write_cmd(lcd_ext->config->table_init_on); LCDPR("[extern]%s dsi init on\n", - lcd_ext->config.name); + lcd_ext->config->name); } } } @@ -1965,10 +1965,10 @@ void mipi_dsi_link_off(struct lcd_config_s *pconf) if (lcd_ext == NULL) { LCDPR("no lcd_extern driver\n"); } else { - if (lcd_ext->config.table_init_off) { - dsi_write_cmd(lcd_ext->config.table_init_off); + if (lcd_ext->config->table_init_off) { + dsi_write_cmd(lcd_ext->config->table_init_off); LCDPR("[extern]%s dsi init off\n", - lcd_ext->config.name); + lcd_ext->config->name); } } } diff --git a/drivers/amlogic/media/vout/lcd/lcd_vout.c b/drivers/amlogic/media/vout/lcd/lcd_vout.c index f2db70b..9d95b9d 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_vout.c +++ b/drivers/amlogic/media/vout/lcd/lcd_vout.c @@ -195,6 +195,9 @@ static struct lcd_config_s lcd_config_dft = { .change_flag = 0, .retry_enable_flag = 0, .retry_enable_cnt = 0, + + .backlight_index = 0xff, + .extern_index = 0xff, }; static struct vinfo_s lcd_vinfo = { @@ -259,12 +262,12 @@ static void lcd_power_ctrl(int status) if (ext_drv) { if (status) { if (ext_drv->power_on) - ext_drv->power_on(ext_drv); + ext_drv->power_on(); else LCDERR("no ext power on\n"); } else { if (ext_drv->power_off) - ext_drv->power_off(ext_drv); + ext_drv->power_off(); else LCDERR("no ext power off\n"); } @@ -567,14 +570,34 @@ static struct notifier_block lcd_bl_select_nb = { .notifier_call = lcd_bl_select_notifier, }; +static int lcd_extern_select_notifier(struct notifier_block *nb, + unsigned long event, void *data) +{ + unsigned int *index; + struct lcd_config_s *pconf = lcd_driver->lcd_config; + + if ((event & LCD_EVENT_EXTERN_SEL) == 0) + return NOTIFY_DONE; + /* LCDPR("%s: 0x%lx\n", __func__, event); */ + + index = (unsigned int *)data; + *index = pconf->extern_index; + if (pconf->lcd_basic.lcd_type == LCD_MIPI) { + if (*index == LCD_EXTERN_INDEX_INVALID) + *index = pconf->lcd_control.mipi_config->extern_init; + } + + return NOTIFY_OK; +} + +static struct notifier_block lcd_extern_select_nb = { + .notifier_call = lcd_extern_select_notifier, +}; + static int lcd_notifier_register(void) { int ret = 0; - ret = aml_lcd_notifier_register(&lcd_bl_select_nb); - if (ret) - LCDERR("register aml_bl_select_notifier failed\n"); - ret = aml_lcd_notifier_register(&lcd_power_encl_on_nb); if (ret) LCDERR("register lcd_power_encl_on_nb failed\n"); @@ -594,6 +617,13 @@ static int lcd_notifier_register(void) if (ret) LCDERR("register lcd_power_screen_restore_nb failed\n"); + ret = aml_lcd_notifier_register(&lcd_bl_select_nb); + if (ret) + LCDERR("register aml_bl_select_notifier failed\n"); + ret = aml_lcd_notifier_register(&lcd_extern_select_nb); + if (ret) + LCDERR("register lcd_extern_select_nb failed\n"); + return 0; } @@ -607,6 +637,7 @@ static void lcd_notifier_unregister(void) aml_lcd_notifier_unregister(&lcd_power_encl_on_nb); aml_lcd_notifier_unregister(&lcd_bl_select_nb); + aml_lcd_notifier_unregister(&lcd_extern_select_nb); } /* **************************************** */ diff --git a/include/linux/amlogic/media/vout/lcd/lcd_extern.h b/include/linux/amlogic/media/vout/lcd/lcd_extern.h index 9037904..c341dff 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_extern.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_extern.h @@ -25,15 +25,15 @@ enum lcd_extern_type_e { LCD_EXTERN_MAX, }; -enum lcd_extern_i2c_bus_e { - LCD_EXTERN_I2C_BUS_AO = 0, - LCD_EXTERN_I2C_BUS_A, - LCD_EXTERN_I2C_BUS_B, - LCD_EXTERN_I2C_BUS_C, - LCD_EXTERN_I2C_BUS_D, - LCD_EXTERN_I2C_BUS_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 */ @@ -57,6 +57,10 @@ struct lcd_extern_config_s { char name[LCD_EXTERN_NAME_LEN_MAX]; enum lcd_extern_type_e type; unsigned char status; + unsigned char pinmux_valid; + unsigned char key_valid; + unsigned char addr_sel; /* internal used */ + unsigned char i2c_addr; unsigned char i2c_addr2; unsigned char i2c_bus; @@ -64,31 +68,33 @@ struct lcd_extern_config_s { unsigned char i2c_sck_gpio_off; unsigned char i2c_sda_gpio; unsigned char i2c_sda_gpio_off; + 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 char cmd_size; - unsigned char table_init_loaded; /* internal use */ unsigned char *table_init_on; unsigned char *table_init_off; - unsigned int table_init_on_cnt; + unsigned char table_init_loaded; /* internal use */ + unsigned int table_init_on_cnt; /* internal use */ }; /* global API */ -#define LCD_EXT_DRIVER_MAX 10 struct aml_lcd_extern_driver_s { - struct lcd_extern_config_s config; + struct lcd_extern_config_s *config; int (*reg_read)(unsigned char reg, unsigned char *buf); int (*reg_write)(unsigned char reg, unsigned char value); - int (*power_on)(struct aml_lcd_extern_driver_s *ext_drv); - int (*power_off)(struct aml_lcd_extern_driver_s *ext_drv); + int (*power_on)(void); + int (*power_off)(void); struct pinctrl *pin; unsigned int pinmux_flag; }; +#define LCD_EXT_I2C_DEV_MAX 10 struct aml_lcd_extern_i2c_dev_s { char name[30]; struct i2c_client *client; diff --git a/include/linux/amlogic/media/vout/lcd/lcd_notify.h b/include/linux/amlogic/media/vout/lcd/lcd_notify.h index e76822a..00b7f76 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_notify.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_notify.h @@ -66,6 +66,7 @@ #define LCD_EVENT_BACKLIGHT_UPDATE (1 << 9) #define LCD_EVENT_GAMMA_UPDATE (1 << 10) +#define LCD_EVENT_EXTERN_SEL (1 << 11) /* lcd frame rate change occurred */ #define LCD_EVENT_FRAME_RATE_ADJUST (1 << 12) diff --git a/include/linux/amlogic/media/vout/lcd/lcd_vout.h b/include/linux/amlogic/media/vout/lcd/lcd_vout.h index a8e8565..7a75f18 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_vout.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_vout.h @@ -384,6 +384,7 @@ struct lcd_clk_gate_ctrl_s { struct lcd_config_s { char *lcd_propname; unsigned int backlight_index; + unsigned int extern_index; struct lcd_basic_s lcd_basic; struct lcd_timing_s lcd_timing; struct lcd_hdr_info_s hdr_info; -- 2.7.4