lcd: premote a common lcd_extern_i2c_probe
authorWeiming Liu <weiming.liu@amlogic.com>
Fri, 13 Apr 2018 10:58:06 +0000 (18:58 +0800)
committerYixun Lan <yixun.lan@amlogic.com>
Wed, 16 May 2018 09:39:26 +0000 (02:39 -0700)
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 <weiming.liu@amlogic.com>
14 files changed:
arch/arm64/boot/dts/amlogic/g12a_s905d2_skt.dts
arch/arm64/boot/dts/amlogic/g12a_s905d2_skt_buildroot.dts
arch/arm64/boot/dts/amlogic/g12a_s905d2_u200.dts
arch/arm64/boot/dts/amlogic/g12a_s905d2_u200_buildroot.dts
arch/arm64/boot/dts/amlogic/mesontxlx_r311-panel.dtsi
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_1g.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_2g.dts
arch/arm64/boot/dts/amlogic/txlx_t962x_r311_720p.dts
drivers/amlogic/media/vout/backlight/aml_bl.c
drivers/amlogic/media/vout/lcd/lcd_extern/ext_default.c
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_DLPC3439.c
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_T5800Q.c
drivers/amlogic/media/vout/lcd/lcd_extern/i2c_tc101.c
include/linux/amlogic/media/vout/lcd/lcd_extern.h

index e062c36..56fc5e5 100644 (file)
                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 {
index 667b5f2..d1bb1cc 100644 (file)
                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 {
index 2eef8e0..944e57b 100644 (file)
                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 {
index 7fd43d1..3c4d22a 100644 (file)
                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 {
index ef5eeaa..010ea2b 100644 (file)
                        type = <0>; /* 0=i2c, 1=spi, 2=mipi */
                        i2c_address = <0x1c>; /* 7bit i2c address */
                        i2c_bus = "i2c_bus_c";
+                       cmd_size = <9>;
                };
        };
 
index 79a82b7..6e81d40 100644 (file)
                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 {
index bc0e0ba..d590fe8 100644 (file)
                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 {
index 06dd29d..7568bd8 100644 (file)
                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 {
index 79a6900..22fbdb5 100644 (file)
@@ -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)) {
index 7b87765..a509a08 100644 (file)
@@ -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");
+
index 506bdd5..2dd7f86 100644 (file)
@@ -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;
-}
index 784d1e2..1fed5a0 100644 (file)
@@ -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 <reg> <> ... <> > 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");
+
index 6438bfd..09d7bc7 100644 (file)
 #include <linux/amlogic/media/vout/lcd/lcd_extern.h>
 #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");
 
index 4c16c74..58306d1 100644 (file)
@@ -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