From 556215ab62c4f6cc9d64119c0b0a0158bc0f033d Mon Sep 17 00:00:00 2001 From: Weiming Liu Date: Fri, 13 Apr 2018 18:58:06 +0800 Subject: [PATCH] lcd: premote a common lcd_extern_i2c_probe PD#164139: lcd: premote a common lcd_extern_i2c_probe premote a common lcd_extern_i2c_probe() function, so it will be shared by various display controller IC Change-Id: I47638520f32a0865829a1fd776c3a9ca626798ba Signed-off-by: Weiming Liu --- arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts | 7 + .../boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts | 6 + arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts | 6 + .../dts/amlogic/g12a_s905d2_u200_buildroot.dts | 6 + .../boot/dts/amlogic/mesontxlx_r311-panel.dtsi | 1 + arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts | 7 + arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts | 6 + .../boot/dts/amlogic/txlx_t962x_r311_720p.dts | 6 + drivers/amlogic/media/vout/backlight/aml_bl.c | 5 + .../media/vout/lcd/lcd_extern/ext_default.c | 187 +++++++------- .../media/vout/lcd/lcd_extern/i2c_DLPC3439.c | 168 +++++++------ .../amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c | 269 +++++++-------------- .../amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c | 236 ++++++++---------- include/linux/amlogic/media/vout/lcd/lcd_extern.h | 5 + 14 files changed, 442 insertions(+), 473 deletions(-) diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts index e062c36..56fc5e5 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts @@ -753,6 +753,13 @@ reg = <0x2c>; /*reg_address for lp8556*/ dev_name = "lp8556"; }; + + lcd_extern_i2c { + compatible = "amlogic, lcd_i2c_T5800Q"; + status = "disabled"; + reg = <0x1c>; /*reg_address for i2c_T5800Q*/ + dev_name = "i2c_T5800Q"; + }; }; &audiobus { diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts index 667b5f2..d1bb1cc 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts @@ -694,6 +694,12 @@ reg = <0x2c>; /*reg_address for lp8556*/ dev_name = "lp8556"; }; + lcd_extern_i2c { + compatible = "amlogic, lcd_i2c_T5800Q"; + status = "disabled"; + reg = <0x1c>; /*reg_address for i2c_T5800Q*/ + dev_name = "i2c_T5800Q"; + }; }; &audiobus { diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts index 2eef8e0..944e57b 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts @@ -796,6 +796,12 @@ reg = <0x2c>; /*reg_address for lp8556*/ dev_name = "lp8556"; }; + lcd_extern_i2c { + compatible = "amlogic, lcd_i2c_T5800Q"; + status = "disabled"; + reg = <0x1c>; /*reg_address for i2c_T5800Q*/ + dev_name = "i2c_T5800Q"; + }; }; &audiobus { diff --git a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts index 7fd43d1..3c4d22a6 100644 --- a/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts +++ b/arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts @@ -864,6 +864,12 @@ reg = <0x2c>; /*reg_address for lp8556*/ dev_name = "lp8556"; }; + lcd_extern_i2c { + compatible = "amlogic, lcd_i2c_T5800Q"; + status = "disabled"; + reg = <0x1c>; /*reg_address for i2c_T5800Q*/ + dev_name = "i2c_T5800Q"; + }; }; &audiobus { diff --git a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi index ef5eeaa..010ea2b 100644 --- a/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi +++ b/arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi @@ -510,6 +510,7 @@ 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/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts index 79a82b7..6e81d40 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts @@ -1438,6 +1438,13 @@ drc_enable = <0>; status = "okay"; }; + + lcd_extern_i2c { + compatible = "amlogic, lcd_i2c_T5800Q"; + status = "disabled"; + reg = <0x1c>; /*reg_address for i2c_T5800Q*/ + dev_name = "i2c_T5800Q"; + }; }; &i2c1 { diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts index bc0e0ba..d590fe8 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts @@ -1437,6 +1437,12 @@ drc_enable = <0>; status = "okay"; }; + lcd_extern_i2c { + compatible = "amlogic, lcd_i2c_T5800Q"; + status = "disabled"; + reg = <0x1c>; /*reg_address for i2c_T5800Q*/ + dev_name = "i2c_T5800Q"; + }; }; &i2c1 { diff --git a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts index 06dd29d..7568bd8 100644 --- a/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts +++ b/arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts @@ -1436,6 +1436,12 @@ drc_enable = <0>; status = "okay"; }; + lcd_extern_i2c { + compatible = "amlogic, lcd_i2c_T5800Q"; + status = "disabled"; + reg = <0x1c>; /*reg_address for i2c_T5800Q*/ + dev_name = "i2c_T5800Q"; + }; }; &i2c1 { diff --git a/drivers/amlogic/media/vout/backlight/aml_bl.c b/drivers/amlogic/media/vout/backlight/aml_bl.c index 79a6900..22fbdb5 100644 --- a/drivers/amlogic/media/vout/backlight/aml_bl.c +++ b/drivers/amlogic/media/vout/backlight/aml_bl.c @@ -643,6 +643,11 @@ static void bl_power_on(void) mutex_lock(&bl_power_mutex); + if ((bl_drv->state & BL_STATE_LCD_ON) == 0) { + BLPR("%s exit, for lcd is off\n", __func__); + goto exit_power_on_bl; + } + if (brightness_bypass == 0) { if ((bl_drv->level == 0) || (bl_drv->state & BL_STATE_BL_ON)) { 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 7b87765..a509a08 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c @@ -43,9 +43,8 @@ #define SPI_CLK_FREQ 10000 /* Hz */ #define SPI_CLK_POL 1 -static struct i2c_client *aml_default_i2c_client; -static struct i2c_client *aml_default_i2c2_client; 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[] = { @@ -220,17 +219,17 @@ 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"); + return -1; + } ret = lcd_extern_i2c_write( - aml_default_i2c_client, + i2c_device->client, &init_table[i+2], (cmd_size-1)); if (init_table[i+cmd_size+1] > 0) mdelay(init_table[i+cmd_size+1]); } else if (type == LCD_EXTERN_INIT_CMD2) { - ret = lcd_extern_i2c_write( - aml_default_i2c2_client, - &init_table[i+2], (cmd_size-1)); - if (init_table[i+cmd_size+1] > 0) - mdelay(init_table[i+cmd_size+1]); + EXTPR("%s not support cmd2\n", __func__); } else { EXTERR("%s(%d: %s): type %d invalid\n", __func__, ext_config->index, @@ -333,13 +332,15 @@ 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"); + return -1; + } ret = lcd_extern_i2c_write( - aml_default_i2c_client, + i2c_device->client, &init_table[i+1], (cmd_size-2)); } else if (type == LCD_EXTERN_INIT_CMD2) { - ret = lcd_extern_i2c_write( - aml_default_i2c2_client, - &init_table[i+1], (cmd_size-2)); + EXTPR("%s not support cmd2\n", __func__); } else { EXTERR("%s(%d: %s): type %d invalid\n", __func__, ext_config->index, @@ -498,96 +499,22 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv) return 0; } -static int aml_default_i2c_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__); - return -ENODEV; - } - - aml_default_i2c_client = client; - - EXTPR("%s OK\n", __func__); - return 0; -} - -static int aml_default_i2c_remove(struct i2c_client *client) -{ - return 0; -} - -static const struct i2c_device_id aml_default_i2c_id[] = { - {LCD_EXTERN_NAME, 0}, - { } -}; -/* MODULE_DEVICE_TABLE(i2c, aml_T5800Q_id); */ - -static struct i2c_driver aml_default_i2c_driver = { - .probe = aml_default_i2c_probe, - .remove = aml_default_i2c_remove, - .id_table = aml_default_i2c_id, - .driver = { - .name = LCD_EXTERN_NAME, - .owner = THIS_MODULE, - }, -}; - int aml_lcd_extern_default_probe(struct aml_lcd_extern_driver_s *ext_drv) { - struct i2c_board_info i2c_info; - struct i2c_adapter *adapter; - struct i2c_client *i2c_client; int ret = 0; ext_config = &ext_drv->config; switch (ext_drv->config.type) { case LCD_EXTERN_I2C: - aml_default_i2c_client = NULL; - aml_default_i2c2_client = NULL; - if (ext_drv->config.i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) { - EXTERR("invalid i2c bus\n"); + if (i2c_device == NULL) { + EXTERR("invalid i2c device\n"); return -1; } - memset(&i2c_info, 0, sizeof(i2c_info)); - adapter = i2c_get_adapter(ext_drv->config.i2c_bus); - if (!adapter) { - EXTERR("%s failed to get i2c adapter\n", - ext_drv->config.name); + if (ext_drv->config.i2c_addr != i2c_device->client->addr) { + EXTERR("invalid i2c addr\n"); return -1; } - - strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE); - i2c_info.type[I2C_NAME_SIZE-1] = '\0'; - i2c_info.addr = ext_drv->config.i2c_addr; - i2c_info.platform_data = &ext_drv->config; - i2c_info.flags = 0; - if (i2c_info.addr > 0x7f) { - EXTERR("%s invalid i2c address: 0x%02x\n", - ext_drv->config.name, ext_drv->config.i2c_addr); - return -1; - } - i2c_client = i2c_new_device(adapter, &i2c_info); - if (!i2c_client) { - EXTERR("%s failed to new i2c device\n", - ext_drv->config.name); - return -1; - } - if (lcd_debug_print_flag) { - EXTPR("%s new i2c device succeed\n", - ext_drv->config.name); - } - - if (!aml_default_i2c_client) { - ret = i2c_add_driver(&aml_default_i2c_driver); - if (ret) { - EXTERR("%s add i2c_driver failed\n", - ext_drv->config.name); - return -1; - } - } break; case LCD_EXTERN_SPI: break; @@ -602,3 +529,83 @@ 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 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); + + 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/i2c_DLPC3439.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c index 506bdd5..2dd7f86 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,8 @@ #define LCD_EXTERN_NAME "i2c_DLPC3439" -static struct i2c_client *aml_DLPC3439_i2c_client; static struct lcd_extern_config_s *ext_config; +static struct aml_lcd_extern_i2c_dev_s *i2c_device; /* Write: ImageCrop: 1920x1080 @@ -81,11 +81,16 @@ static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) int ret = 0; lcd_extern_pinmux_set(ext_drv, 1); - lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_1, 9); - lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_2, 5); - lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_3, 5); - lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_4, 2); - lcd_extern_i2c_write(aml_DLPC3439_i2c_client, data_5, 2); + + if (i2c_device == 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); EXTPR("%s\n", __func__); return ret; @@ -115,91 +120,104 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv) return ret; } -static int aml_DLPC3439_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +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) { + EXTERR("invalid i2c device\n"); + return -1; + } + if (ext_drv->config.i2c_addr != i2c_device->client->addr) { + EXTERR("invalid i2c addr\n"); + return -1; + } + + ret = lcd_extern_driver_update(ext_drv); + + if (lcd_debug_print_flag) + EXTPR("%s: %d\n", __func__, ret); + 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_DLPC3439"; + } + 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; + } - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - EXTERR("%s: functionality check failed\n", __func__); - else - aml_DLPC3439_i2c_client = client; + 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); - EXTPR("%s OK\n", __func__); return 0; } -static int aml_DLPC3439_i2c_remove(struct i2c_client *client) +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_DLPC3439_i2c_id[] = { - {LCD_EXTERN_NAME, 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", + }, + {}, }; -/* MODULE_DEVICE_TABLE(i2c, aml_DLPC3439_id); */ +#endif -static struct i2c_driver aml_DLPC3439_i2c_driver = { - .probe = aml_DLPC3439_i2c_probe, - .remove = aml_DLPC3439_i2c_remove, - .id_table = aml_DLPC3439_i2c_id, +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 = LCD_EXTERN_NAME, + .name = "i2c_DLPC3439", .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = aml_lcd_extern_i2c_dt_match, +#endif }, }; -int aml_lcd_extern_i2c_DLPC3439_probe(struct aml_lcd_extern_driver_s *ext_drv) -{ - struct i2c_board_info i2c_info; - struct i2c_adapter *adapter; - struct i2c_client *i2c_client; - int ret = 0; - - ext_config = &ext_drv->config; - if (ext_drv->config.i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) { - EXTERR("invalid i2c bus\n"); - return -1; - } - memset(&i2c_info, 0, sizeof(i2c_info)); - - adapter = i2c_get_adapter(ext_drv->config.i2c_bus); - if (!adapter) { - EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name); - return -1; - } - - strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE); - i2c_info.addr = ext_drv->config.i2c_addr; - i2c_info.platform_data = &ext_drv->config; - i2c_info.flags = 0; - if (i2c_info.addr > 0x7f) { - EXTERR("%s invalid i2c address: 0x%02x\n", - ext_drv->config.name, ext_drv->config.i2c_addr); - return -1; - } - i2c_client = i2c_new_device(adapter, &i2c_info); - 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_DLPC3439_i2c_client) { - ret = i2c_add_driver(&aml_DLPC3439_i2c_driver); - if (ret) { - EXTERR("%s add i2c_driver failed\n", - ext_drv->config.name); - return -1; - } - } +module_i2c_driver(aml_lcd_extern_i2c_driver); - ret = lcd_extern_driver_update(ext_drv); +MODULE_AUTHOR("AMLOGIC"); +MODULE_DESCRIPTION("lcd extern driver"); +MODULE_LICENSE("GPL"); - if (lcd_debug_print_flag) - EXTPR("%s: %d\n", __func__, ret); - return ret; -} diff --git a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c index 784d1e2..1fed5a0 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c @@ -30,8 +30,8 @@ #define LCD_EXTERN_NAME "i2c_T5800Q" -static struct i2c_client *aml_T5800Q_i2c_client; 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[] = { @@ -69,47 +69,6 @@ static int lcd_extern_i2c_write(struct i2c_client *i2client, return ret; } -#if 0 -static int lcd_extern_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("i2c read failed [addr 0x%02x]\n", i2client->addr); - - return ret; -} -#endif - -static int lcd_extern_reg_read(unsigned char reg, unsigned char *buf) -{ - int ret = 0; - - return ret; -} - -static int lcd_extern_reg_write(unsigned char reg, unsigned char value) -{ - int ret = 0; - - return ret; -} static int lcd_extern_power_cmd(unsigned char *init_table, int flag) { @@ -151,7 +110,12 @@ 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) { - ret = lcd_extern_i2c_write(aml_T5800Q_i2c_client, + if (i2c_device == NULL) { + EXTERR("invalid i2c device\n"); + return -1; + } + ret = lcd_extern_i2c_write( + i2c_device->client, &init_table[i+1], (cmd_size-2)); } else { EXTERR("%s(%d: %s): power_type %d is invalid\n", @@ -210,185 +174,138 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv) ext_drv->config.table_init_on = init_on_table; ext_drv->config.table_init_off = init_off_table; } - ext_drv->reg_read = lcd_extern_reg_read; - ext_drv->reg_write = lcd_extern_reg_write; ext_drv->power_on = lcd_extern_power_on; ext_drv->power_off = lcd_extern_power_off; return 0; } -/* ********************************************************* - * debug function - * ********************************************************* - */ -static const char *lcd_extern_debug_usage_str = { -"Usage:\n" -" echo <> ... <> > write ; T5800Q i2c command write, 7 parameters without address\n" -}; - -static ssize_t lcd_extern_debug_help(struct class *class, - struct class_attribute *attr, char *buf) +int aml_lcd_extern_i2c_T5800Q_probe(struct aml_lcd_extern_driver_s *ext_drv) { - return sprintf(buf, "%s\n", lcd_extern_debug_usage_str); -} + int ret = 0; -static ssize_t lcd_extern_debug_write(struct class *class, - struct class_attribute *attr, const char *buf, size_t count) -{ - unsigned int ret; - unsigned int temp[8]; - unsigned char data[8]; - int i; - - memset(temp, 0, (sizeof(unsigned int) * 8)); - ret = sscanf(buf, "%x %x %x %x %x %x %x", - &temp[0], &temp[1], &temp[2], &temp[3], - &temp[4], &temp[5], &temp[6]); - EXTPR("T5800Q i2c write:\n"); - for (i = 0; i < 7; i++) { - data[i] = (unsigned char)temp[i]; - pr_info("0x%02x ", data[i]); + ext_config = &ext_drv->config; + if (i2c_device == NULL) { + EXTERR("invalid i2c device\n"); + return -1; } - pr_info("\n"); - lcd_extern_i2c_write(aml_T5800Q_i2c_client, data, 7); - - if (ret != 1 || ret != 2) - return -EINVAL; - - return count; -} - -static struct class_attribute lcd_extern_class_attrs[] = { - __ATTR(write, 0644, - lcd_extern_debug_help, lcd_extern_debug_write), -}; - -static struct class *debug_class; -static int creat_lcd_extern_class(void) -{ - int i; - - debug_class = class_create(THIS_MODULE, LCD_EXTERN_NAME); - if (IS_ERR(debug_class)) { - EXTERR("create debug class failed\n"); + if (ext_drv->config.i2c_addr != i2c_device->client->addr) { + EXTERR("invalid i2c addr\n"); return -1; } - for (i = 0; i < ARRAY_SIZE(lcd_extern_class_attrs); i++) { - if (class_create_file(debug_class, - &lcd_extern_class_attrs[i])) { - EXTERR("create debug attribute %s failed\n", - lcd_extern_class_attrs[i].attr.name); - } - } + ret = lcd_extern_driver_update(ext_drv); + EXTPR("%s: %d\n", __func__, ret); + return ret; +} +int aml_lcd_extern_i2c_T5800Q_remove(void) +{ return 0; } -#if 0 -static int remove_lcd_extern_class(void) +static int lcd_extern_i2c_config_from_dts(struct device *dev, + struct aml_lcd_extern_i2c_dev_s *i2c_device) { - int i; - - for (i = 0; i < ARRAY_SIZE(lcd_extern_class_attrs); i++) - class_remove_file(debug_class, &lcd_extern_class_attrs[i]); + int ret; + struct device_node *np = dev->of_node; + const char *str; - class_destroy(debug_class); - debug_class = NULL; + 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; } -#endif -/* ********************************************************* */ -static int aml_T5800Q_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +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("%s: functionality check failed\n", __func__); + EXTERR("I2C check functionality failed."); return -ENODEV; } - aml_T5800Q_i2c_client = client; + 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); - EXTPR("%s OK\n", __func__); return 0; } -static int aml_T5800Q_i2c_remove(struct i2c_client *client) +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_T5800Q_i2c_id[] = { - {LCD_EXTERN_NAME, 0}, - { } +static const struct i2c_device_id aml_lcd_extern_i2c_id[] = { + {"i2c_T5800Q", 0}, + {} }; -/* MODULE_DEVICE_TABLE(i2c, aml_T5800Q_id); */ -static struct i2c_driver aml_T5800Q_i2c_driver = { - .probe = aml_T5800Q_i2c_probe, - .remove = aml_T5800Q_i2c_remove, - .id_table = aml_T5800Q_i2c_id, +#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 = LCD_EXTERN_NAME, + .name = "i2c_T5800Q", .owner = THIS_MODULE, +#ifdef CONFIG_OF + .of_match_table = aml_lcd_extern_i2c_dt_match, +#endif }, }; -int aml_lcd_extern_i2c_T5800Q_probe(struct aml_lcd_extern_driver_s *ext_drv) +static int __init aml_lcd_extern_i2c_init(void) { - struct i2c_board_info i2c_info; - struct i2c_adapter *adapter; - struct i2c_client *i2c_client; - int ret = 0; + int ret; - ext_config = &ext_drv->config; - if (ext_drv->config.i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) { - EXTERR("invalid i2c bus\n"); - return -1; - } - memset(&i2c_info, 0, sizeof(i2c_info)); + //if (lcd_debug_print_flag) + EXTPR("%s\n", __func__); - adapter = i2c_get_adapter(ext_drv->config.i2c_bus); - if (!adapter) { - EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name); - return -1; + ret = i2c_add_driver(&aml_lcd_extern_i2c_driver); + if (ret) { + EXTERR("driver register failed\n"); + return -ENODEV; } + return ret; +} - strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE); - i2c_info.type[I2C_NAME_SIZE-1] = '\0'; - i2c_info.addr = ext_drv->config.i2c_addr; - i2c_info.platform_data = &ext_drv->config; - i2c_info.flags = 0; - if (i2c_info.addr > 0x7f) { - EXTERR("%s invalid i2c address: 0x%02x\n", - ext_drv->config.name, ext_drv->config.i2c_addr); - return -1; - } - i2c_client = i2c_new_device(adapter, &i2c_info); - if (!i2c_client) { - EXTERR("%s failed to new i2c device\n", ext_drv->config.name); - return -1; - } - if (lcd_debug_print_flag) - EXTPR("%s new i2c device succeed\n", ext_drv->config.name); - - if (!aml_T5800Q_i2c_client) { - ret = i2c_add_driver(&aml_T5800Q_i2c_driver); - if (ret) { - EXTERR("%s add i2c_driver failed\n", - ext_drv->config.name); - return -1; - } - } +static void __exit aml_lcd_extern_i2c_exit(void) +{ + i2c_del_driver(&aml_lcd_extern_i2c_driver); +} - ret = lcd_extern_driver_update(ext_drv); - creat_lcd_extern_class(); - if (lcd_debug_print_flag) - EXTPR("%s: %d\n", __func__, ret); - return ret; -} +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_tc101.c b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c index 6438bfd..09d7bc7 100644 --- a/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c +++ b/drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c @@ -28,12 +28,12 @@ #include #include "lcd_extern.h" -static struct lcd_extern_config_s *ext_config; -static struct i2c_client *aml_tc101_i2c_client; +#define LCD_EXTERN_NAME "i2c_tc101" -#define LCD_EXTERN_NAME "lcd_i2c_tc101" +static struct lcd_extern_config_s *ext_config; +static struct aml_lcd_extern_i2c_dev_s *i2c_device; -static unsigned char i2c_init_table[][3] = { +static unsigned char init_on_table[][3] = { /* {0xff, 0xff, 20},//delay mark(20ms) */ {0xf8, 0x30, 0xb2}, {0xf8, 0x33, 0xc2}, @@ -43,8 +43,8 @@ static unsigned char i2c_init_table[][3] = { {0xff, 0xff, 0xff},/* end mark */ }; -static int aml_i2c_write(struct i2c_client *i2client, unsigned char *buff, - unsigned int len) +static int lcd_extern_i2c_write(struct i2c_client *i2client, + unsigned char *buff, unsigned int len) { int ret = 0; struct i2c_msg msg[] = { @@ -53,60 +53,15 @@ static int aml_i2c_write(struct i2c_client *i2client, unsigned char *buff, .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; -} -#if 0 -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; -} - -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; + if (ret < 0) + EXTERR("i2c write failed [addr 0x%02x]\n", i2client->addr); return ret; } -#endif static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) { @@ -115,18 +70,23 @@ static int lcd_extern_power_on(struct aml_lcd_extern_driver_s *ext_drv) int ret = 0; lcd_extern_pinmux_set(ext_drv, 1); + + if (i2c_device == NULL) { + EXTERR("invalid i2c device\n"); + return -1; + } while (ending_flag == 0) { - if ((i2c_init_table[i][0] == 0xff) && - (i2c_init_table[i][1] == 0xff)) { /* special mark */ - if (i2c_init_table[i][2] == 0xff) /* ending flag */ + if ((init_on_table[i][0] == 0xff) && + (init_on_table[i][1] == 0xff)) { /* special mark */ + if (init_on_table[i][2] == 0xff) /* ending flag */ ending_flag = 1; else /* delay flag */ - mdelay(i2c_init_table[i][2]); + mdelay(init_on_table[i][2]); } else { - tData[0] = i2c_init_table[i][0]; - tData[1] = i2c_init_table[i][1]; - tData[2] = i2c_init_table[i][2]; - aml_i2c_write(aml_tc101_i2c_client, tData, 3); + 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); } i++; } @@ -157,92 +117,104 @@ static int lcd_extern_driver_update(struct aml_lcd_extern_driver_s *ext_drv) return ret; } -static int aml_tc101_i2c_probe(struct i2c_client *client, - const struct i2c_device_id *id) +int aml_lcd_extern_i2c_tc101_probe(struct aml_lcd_extern_driver_s *ext_drv) { + int ret = 0; - if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) - EXTERR("%s: functionality check failed\n", __func__); - else - aml_tc101_i2c_client = client; + ext_config = &ext_drv->config; + if (i2c_device == 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("%s OK\n", __func__); - return 0; + ret = lcd_extern_driver_update(ext_drv); + + if (lcd_debug_print_flag) + EXTPR("%s: %d\n", __func__, ret); + return ret; } -static int aml_tc101_i2c_remove(struct i2c_client *client) +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 const struct i2c_device_id aml_tc101_i2c_id[] = { - {LCD_EXTERN_NAME, 0}, - { } -}; -/* MODULE_DEVICE_TABLE(i2c, aml_tc101_id); */ +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; + } -static struct i2c_driver aml_tc101_i2c_driver = { - .probe = aml_tc101_i2c_probe, - .remove = aml_tc101_i2c_remove, - .id_table = aml_tc101_i2c_id, - .driver = { - .name = LCD_EXTERN_NAME, - .owner = THIS_MODULE, - }, -}; + 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); -int aml_lcd_extern_i2c_tc101_probe(struct aml_lcd_extern_driver_s *ext_drv) + return 0; +} + +static int aml_lcd_extern_i2c_remove(struct i2c_client *client) { - struct i2c_board_info i2c_info; - struct i2c_adapter *adapter; - struct i2c_client *i2c_client; - int ret = 0; + kfree(i2c_device); + i2c_set_clientdata(client, NULL); - ext_config = &ext_drv->config; - if (ext_drv->config.i2c_bus == LCD_EXTERN_I2C_BUS_INVALID) { - EXTERR("invalid i2c bus\n"); - return -1; - } - memset(&i2c_info, 0, sizeof(i2c_info)); + return 0; +} - adapter = i2c_get_adapter(ext_drv->config.i2c_bus); - if (!adapter) { - EXTERR("%s failed to get i2c adapter\n", ext_drv->config.name); - return -1; - } +static const struct i2c_device_id aml_lcd_extern_i2c_id[] = { + {"i2c_tc101", 0}, + {} +}; - strncpy(i2c_info.type, ext_drv->config.name, I2C_NAME_SIZE); - i2c_info.addr = ext_drv->config.i2c_addr; - i2c_info.platform_data = &ext_drv->config; - i2c_info.flags = 0; - if (i2c_info.addr > 0x7f) { - EXTERR("%s invalid i2c address: 0x%02x\n", - ext_drv->config.name, ext_drv->config.i2c_addr); - return -1; - } - i2c_client = i2c_new_device(adapter, &i2c_info); - 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); - } - } +#ifdef CONFIG_OF +static const struct of_device_id aml_lcd_extern_i2c_dt_match[] = { + { + .compatible = "amlogic, lcd_i2c_tc101", + }, + {}, +}; +#endif - if (!aml_tc101_i2c_client) { - ret = i2c_add_driver(&aml_tc101_i2c_driver); - if (ret) { - EXTERR("%s add i2c_driver failed\n", - ext_drv->config.name); - return -1; - } - } +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 + }, +}; - ret = lcd_extern_driver_update(ext_drv); +module_i2c_driver(aml_lcd_extern_i2c_driver); - if (lcd_debug_print_flag) - EXTPR("%s: %d\n", __func__, ret); - return ret; -} +MODULE_AUTHOR("AMLOGIC"); +MODULE_DESCRIPTION("lcd extern driver"); +MODULE_LICENSE("GPL"); diff --git a/include/linux/amlogic/media/vout/lcd/lcd_extern.h b/include/linux/amlogic/media/vout/lcd/lcd_extern.h index 4c16c74..58306d1 100644 --- a/include/linux/amlogic/media/vout/lcd/lcd_extern.h +++ b/include/linux/amlogic/media/vout/lcd/lcd_extern.h @@ -89,6 +89,11 @@ struct aml_lcd_extern_driver_s { unsigned int pinmux_flag; }; +struct aml_lcd_extern_i2c_dev_s { + char name[20]; + struct i2c_client *client; +}; + extern struct aml_lcd_extern_driver_s *aml_lcd_extern_get_driver(int index); #endif -- 2.7.4