From 6778948f9de86c3cfaf36725a7c87dcff9ba247f Mon Sep 17 00:00:00 2001 From: hc <hc@nodka.com> Date: Mon, 11 Dec 2023 08:20:59 +0000 Subject: [PATCH] kernel_5.10 no rt --- kernel/drivers/misc/lt7911d-fb-notifier.c | 547 ++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 files changed, 509 insertions(+), 38 deletions(-) diff --git a/kernel/drivers/misc/lt7911d-fb-notifier.c b/kernel/drivers/misc/lt7911d-fb-notifier.c index 11da6bb..1c46ecc 100644 --- a/kernel/drivers/misc/lt7911d-fb-notifier.c +++ b/kernel/drivers/misc/lt7911d-fb-notifier.c @@ -5,19 +5,457 @@ #include <linux/kernel.h> #include <linux/delay.h> +#include <linux/i2c.h> #include <linux/platform_device.h> +#include <linux/regulator/consumer.h> #include <linux/gpio/consumer.h> #include <linux/module.h> #include <linux/of.h> #include <linux/of_gpio.h> #include <linux/notifier.h> #include <linux/fb.h> +#include <linux/regmap.h> +#include <linux/clk.h> +#include "lt7911d-fw.h" struct lt7911d { struct device *dev; - struct gpio_descs *gpios; + struct regmap *regmap; + struct serdes_init_seq *serdes_init_seq; + struct gpio_desc *reset_gpio; + struct gpio_desc *enable_gpio; struct notifier_block fb_notif; int fb_blank; +}; + +static int Datalen = 17594; +/*to save hdcp key */ +static unsigned char HdcpKey[286]; +/*the buffer to read flash, its size should be equal the size of bin, max size is 24KB*/ +static unsigned char ReadFirmware[17594]; +/*The buffer to read flash, hex->bin->txt*/ +//static unsigned char FirmwareData[17594]; + +static int I2C_Write_Byte(struct lt7911d *lt7911d, unsigned char reg, unsigned char val) +{ + int ret; + + ret = regmap_write(lt7911d->regmap, reg, val); + if (ret < 0) { + pr_info("failed to write lt7911d register 0x%x: %d\n", reg, ret); + return ret; + } + return 0; +} + +static unsigned char I2C_Read_Byte(struct lt7911d *lt7911d, unsigned char reg) +{ + int ret; + unsigned int val; + + ret = regmap_read(lt7911d->regmap, reg, &val); + if (ret < 0) { + pr_info("failed to read lt7911d register 0x%x: %d\n", reg, ret); + return ret; + } + + return (unsigned char)val; +} + +static bool lt7911d_check_chip_id(struct lt7911d *lt7911d) +{ + unsigned char id_h, id_l; + + /*0x80ee=0x01 to enable i2c interface*/ + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + /*write bank 0xa0, read 0xa000 and 0xa001*/ + I2C_Write_Byte(lt7911d, 0xFF, 0xA0); + id_h = I2C_Read_Byte(lt7911d, 0x00); + id_l = I2C_Read_Byte(lt7911d, 0x01); + + /*chip id=0x1605*/ + if ((id_h == 0x16) && (id_l == 0x05)) { + pr_info("%s chip id =0x1605\n", __func__); + /*0x80ee=0x00 to disable i2c*/ + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x00); + return true; + } else { + pr_info("%s chip id 0x%x is not 0x1605\n", __func__, (id_h << 8) | id_l); + /*0x80ee=0x00 to disable i2c*/ + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x00); + return false; + } +} + +static int lt7911d_check_fw_version(struct lt7911d *lt7911d) +{ + unsigned char fw; + + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + + /*read 0xD211*/ + I2C_Write_Byte(lt7911d, 0xFF, 0xD2); + fw = I2C_Read_Byte(lt7911d, 0x11); + + /*fw version address is 0x1dfb*/ + if (fw < FirmwareData[0x1dfb]) { + pr_info("%s fw %d<%d, need to upgrade\n", __func__, fw, FirmwareData[0x1dfb]); + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x00); + return 0; + } else { + pr_info("%s fw %d>=%d, no need upgrade\n", __func__, fw, FirmwareData[0x1dfb]); + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x00); + return -1; + } +} + +static void lt7911d_config_para(struct lt7911d *lt7911d) +{ + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x5E, 0xC0); + I2C_Write_Byte(lt7911d, 0x58, 0x00); + I2C_Write_Byte(lt7911d, 0x59, 0x51); + I2C_Write_Byte(lt7911d, 0x5A, 0x92); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); +} + +static void lt7911d_block_erase(struct lt7911d *lt7911d) +{ + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + I2C_Write_Byte(lt7911d, 0x5A, 0x86); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x5B, 0x00); + I2C_Write_Byte(lt7911d, 0x5C, 0x00); + I2C_Write_Byte(lt7911d, 0x5D, 0x00); + I2C_Write_Byte(lt7911d, 0x5A, 0x83); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + + /*The time to waiting for earse flash*/ + msleep(500); +} + +/*If earse flash will erase the hdcp key, so need to backup firstly*/ +static void SaveHdcpKeyFromFlash(struct lt7911d *lt7911d) +{ + unsigned int StartAddr; + unsigned int npage, i, j; + unsigned char npagelen = 0; + unsigned char addr[3] = {0}; + + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + I2C_Write_Byte(lt7911d, 0xFF, 0x90); + I2C_Write_Byte(lt7911d, 0x02, 0xdf); + I2C_Write_Byte(lt7911d, 0x02, 0xff); + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0x5a, 0x86); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); + + /*The first address of HDCP KEY*/ + StartAddr = 0x006000; + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + + /*hdcp key size is 286 byte*/ + npage = 18; + npagelen = 16; + + for (i = 0; i < npage; i++) { + I2C_Write_Byte(lt7911d, 0x5E, 0x6f); + I2C_Write_Byte(lt7911d, 0x5A, 0xA2); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x5B, addr[0]); + I2C_Write_Byte(lt7911d, 0x5C, addr[1]); + I2C_Write_Byte(lt7911d, 0x5D, addr[2]); + I2C_Write_Byte(lt7911d, 0x5A, 0x92); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x58, 0x01); + + if (i == 17) + npagelen = 14; + + for (j = 0; j < npagelen; j++) + HdcpKey[i * 16 + j] = I2C_Read_Byte(lt7911d, 0x5F); + + StartAddr += 16; + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + } + + I2C_Write_Byte(lt7911d, 0x5a, 0x8a); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); +} + +static void lt7911d_write_firmware_to_flash(struct lt7911d *lt7911d) +{ + unsigned int StartAddr; + unsigned int npage, i, j; + unsigned char npagelen = 0; + unsigned char addr[3] = {0}; + + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + I2C_Write_Byte(lt7911d, 0xFF, 0x90); + I2C_Write_Byte(lt7911d, 0x02, 0xdf); + I2C_Write_Byte(lt7911d, 0x02, 0xff); + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0x5a, 0x86); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); + + /*The first address of flash��Max Size 24K*/ + StartAddr = 0x000000; + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + + if (Datalen % 16) { + /*Datalen is the length of the firmware.*/ + npage = Datalen / 16 + 1; + } else { + npage = Datalen / 16; + } + npagelen = 16; + + for (i = 0; i < npage; i++) { + I2C_Write_Byte(lt7911d, 0x5A, 0x86); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + + I2C_Write_Byte(lt7911d, 0x5E, 0xef); + I2C_Write_Byte(lt7911d, 0x5A, 0xA2); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x58, 0x01); + + if ((Datalen - i * 16) < 16) + npagelen = Datalen - i*16; + + for (j = 0; j < npagelen; j++) { + /*please just continue to write data to 0x59,*/ + /*and lt7911d will increase the address auto use 0xff*/ + /*as insufficient data if datelen%16 is not zero*/ + I2C_Write_Byte(lt7911d, 0x59, FirmwareData[i*16 + j]); + } + + /*change the first address*/ + I2C_Write_Byte(lt7911d, 0x5B, addr[0]); + I2C_Write_Byte(lt7911d, 0x5C, addr[1]); + I2C_Write_Byte(lt7911d, 0x5D, addr[2]); + I2C_Write_Byte(lt7911d, 0x5E, 0xE0); + I2C_Write_Byte(lt7911d, 0x5A, 0x92); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + + StartAddr += 16; + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + } + + I2C_Write_Byte(lt7911d, 0x5a, 0x8a); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); + + /*reset fifo*/ + I2C_Write_Byte(lt7911d, 0xFF, 0x90); + I2C_Write_Byte(lt7911d, 0x02, 0xDF); + I2C_Write_Byte(lt7911d, 0x02, 0xFF); + msleep(20); +} + +static void lt7911d_write_hdcpkey_to_flash(struct lt7911d *lt7911d) +{ + unsigned int StartAddr; + unsigned int npage, i, j; + unsigned char npagelen = 0; + unsigned char addr[3] = {0}; + + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + I2C_Write_Byte(lt7911d, 0xFF, 0x90); + I2C_Write_Byte(lt7911d, 0x02, 0xdf); + I2C_Write_Byte(lt7911d, 0x02, 0xff); + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0x5a, 0x86); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); + + /*hdcp key first address*/ + StartAddr = 0x006000; + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + + npage = 18; + npagelen = 16; + + for (i = 0; i < npage; i++) { + I2C_Write_Byte(lt7911d, 0x5A, 0x86); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + + I2C_Write_Byte(lt7911d, 0x5E, 0xef); + I2C_Write_Byte(lt7911d, 0x5A, 0xA2); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x58, 0x01); + + if (i == 17) + npagelen = 14; + + for (j = 0; j < npagelen; j++) { + /*please just continue to write data to 0x59,*/ + /*and lt7911d will increase the address auto use 0xff*/ + /*as insufficient data if datelen%16 is not zero .*/ + I2C_Write_Byte(lt7911d, 0x59, HdcpKey[i*16 + j]); + } + + if (npagelen == 14) { + I2C_Write_Byte(lt7911d, 0x59, 0xFF); + I2C_Write_Byte(lt7911d, 0x59, 0xFF); + } + + /*change the first address*/ + I2C_Write_Byte(lt7911d, 0x5B, addr[0]); + I2C_Write_Byte(lt7911d, 0x5C, addr[1]); + I2C_Write_Byte(lt7911d, 0x5D, addr[2]); + I2C_Write_Byte(lt7911d, 0x5E, 0xE0); + I2C_Write_Byte(lt7911d, 0x5A, 0x92); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + + StartAddr += 16; + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + } + + I2C_Write_Byte(lt7911d, 0x5a, 0x8a); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); + + /*reset fifo*/ + I2C_Write_Byte(lt7911d, 0xFF, 0x90); + I2C_Write_Byte(lt7911d, 0x02, 0xDF); + I2C_Write_Byte(lt7911d, 0x02, 0xFF); + msleep(20); +} + +static void lt7911d_read_firmware_from_flash(struct lt7911d *lt7911d) +{ + unsigned int StartAddr; + unsigned int npage, i, j; + unsigned char npagelen = 0; + unsigned char addr[3] = {0}; + + memset(ReadFirmware, 0, sizeof(ReadFirmware)); + + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x01); + I2C_Write_Byte(lt7911d, 0xFF, 0x90); + I2C_Write_Byte(lt7911d, 0x02, 0xdf); + I2C_Write_Byte(lt7911d, 0x02, 0xff); + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0x5a, 0x86); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); + + /*the first address of firmware*/ + StartAddr = 0x000000; + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + + if (Datalen % 16) + npage = Datalen / 16 + 1; + else + npage = Datalen / 16; + + npagelen = 16; + + for (i = 0; i < npage; i++) { + I2C_Write_Byte(lt7911d, 0x5E, 0x6f); + I2C_Write_Byte(lt7911d, 0x5A, 0xA2); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x5B, addr[0]); + I2C_Write_Byte(lt7911d, 0x5C, addr[1]); + I2C_Write_Byte(lt7911d, 0x5D, addr[2]); + I2C_Write_Byte(lt7911d, 0x5A, 0x92); + I2C_Write_Byte(lt7911d, 0x5A, 0x82); + I2C_Write_Byte(lt7911d, 0x58, 0x01); + + if ((Datalen - i * 16) < 16) + npagelen = Datalen - i*16; + + for (j = 0; j < npagelen; j++) { + /*please just continue to read data from 0x5f*/ + /*lt7911d will increase the address auto*/ + ReadFirmware[i*16 + j] = I2C_Read_Byte(lt7911d, 0x5F); + } + + StartAddr += 16; + /*change the first address*/ + addr[0] = (StartAddr & 0xFF0000) >> 16; + addr[1] = (StartAddr & 0xFF00) >> 8; + addr[2] = StartAddr & 0xFF; + } + + I2C_Write_Byte(lt7911d, 0x5a, 0x8a); + I2C_Write_Byte(lt7911d, 0x5a, 0x82); +} + +static int lt7911_compare_firmware(struct lt7911d *lt7911d) +{ + unsigned int len; + + for (len = 0; len < Datalen; len++) { + if (ReadFirmware[len] != FirmwareData[len]) { + pr_info("%s: ReadFirmware[%d] 0x%x != 0x%x FirmwareData[%d]\n", + __func__, len, ReadFirmware[len], FirmwareData[len], len); + return -1; + } + } + return 0; +} + +static int lt7911d_firmware_upgrade(struct lt7911d *lt7911d) +{ + int ret = 0; + + if (lt7911d_check_chip_id(lt7911d)) { + if (lt7911d_check_fw_version(lt7911d) == 0) { + lt7911d_config_para(lt7911d); + SaveHdcpKeyFromFlash(lt7911d); + lt7911d_block_erase(lt7911d); + lt7911d_write_firmware_to_flash(lt7911d); + lt7911d_write_hdcpkey_to_flash(lt7911d); + lt7911d_read_firmware_from_flash(lt7911d); + + if (!lt7911_compare_firmware(lt7911d)) { + pr_info("%s: upgrade success\n", __func__); + ret = 0; + } else { + pr_info("%s: upgrade Fail\n", __func__); + ret = -1; + } + } + } else { + pr_info("the chip lt7911d is offline\n"); + ret = 0; + } + + I2C_Write_Byte(lt7911d, 0xFF, 0x80); + I2C_Write_Byte(lt7911d, 0xEE, 0x00); + + return ret; +} + +static const struct regmap_config lt7911d_regmap_config = { + .name = "lt7911d", + .reg_bits = 8, + .val_bits = 8, + .max_register = 0x100, }; static int lt7911d_fb_notifier_callback(struct notifier_block *self, @@ -26,7 +464,6 @@ struct lt7911d *lt7911d = container_of(self, struct lt7911d, fb_notif); struct fb_event *evdata = data; int fb_blank = *(int *)evdata->data; - int i; if (event != FB_EVENT_BLANK) return 0; @@ -35,12 +472,12 @@ return 0; if (fb_blank == FB_BLANK_UNBLANK) { - for (i = 0; i < lt7911d->gpios->ndescs; i++) - gpiod_direction_output(lt7911d->gpios->desc[i], 1); - msleep(20); - for (i = 0; i < lt7911d->gpios->ndescs; i++) - gpiod_direction_output(lt7911d->gpios->desc[i], 0); - msleep(500); + if (lt7911d->reset_gpio) { + gpiod_direction_output(lt7911d->reset_gpio, 1); + msleep(20); + gpiod_direction_output(lt7911d->reset_gpio, 0); + msleep(400); + } } lt7911d->fb_blank = fb_blank; @@ -48,26 +485,36 @@ return 0; } -static int lt7911d_fb_notifier_probe(struct platform_device *pdev) +static int lt7911d_i2c_probe(struct i2c_client *client, + const struct i2c_device_id *id) { - struct device *dev = &pdev->dev; + struct device *dev = &client->dev; struct lt7911d *lt7911d; - int i, ret; + int ret = 0, i = 0; lt7911d = devm_kzalloc(dev, sizeof(*lt7911d), GFP_KERNEL); if (!lt7911d) return -ENOMEM; lt7911d->dev = dev; - platform_set_drvdata(pdev, lt7911d); + i2c_set_clientdata(client, lt7911d); - lt7911d->gpios = devm_gpiod_get_array(dev, "reset", GPIOD_OUT_LOW); - if (IS_ERR(lt7911d->gpios)) - return dev_err_probe(dev, PTR_ERR(lt7911d->gpios), + lt7911d->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); + if (IS_ERR(lt7911d->reset_gpio)) + return dev_err_probe(dev, PTR_ERR(lt7911d->reset_gpio), "failed to acquire reset gpio\n"); - for (i = 0; i < lt7911d->gpios->ndescs; i++) - gpiod_set_consumer_name(lt7911d->gpios->desc[i], "lt7911d-reset"); + gpiod_set_consumer_name(lt7911d->reset_gpio, "lt7911d-reset"); + + lt7911d->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW); + if (IS_ERR(lt7911d->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(lt7911d->enable_gpio), + "failed to acquire enable gpio\n"); + + lt7911d->regmap = devm_regmap_init_i2c(client, <7911d_regmap_config); + if (IS_ERR(lt7911d->regmap)) + return dev_err_probe(dev, PTR_ERR(lt7911d->regmap), + "failed to initialize regmap\n"); lt7911d->fb_blank = FB_BLANK_UNBLANK; lt7911d->fb_notif.notifier_call = lt7911d_fb_notifier_callback; @@ -75,45 +522,69 @@ if (ret) return dev_err_probe(dev, ret, "failed to register fb client\n"); + for (i = 0; i < 3; i++) { + if (!lt7911d_firmware_upgrade(lt7911d)) + break; + } + + dev_info(dev, "%s end\n", __func__); + return 0; } -static int lt7911d_fb_notifier_remove(struct platform_device *pdev) +static void lt7911d_i2c_shutdown(struct i2c_client *client) { - struct lt7911d *lt7911d = platform_get_drvdata(pdev); + struct lt7911d *lt7911d = i2c_get_clientdata(client); + + gpiod_direction_output(lt7911d->reset_gpio, 1); + msleep(20); +} + +static int lt7911d_i2c_remove(struct i2c_client *client) +{ + struct lt7911d *lt7911d = i2c_get_clientdata(client); fb_unregister_client(<7911d->fb_notif); return 0; } -static void lt7911d_fb_notifier_shutdown(struct platform_device *pdev) -{ - struct lt7911d *lt7911d = platform_get_drvdata(pdev); - int i; +static const struct i2c_device_id lt7911d_i2c_table[] = { + { "lt7911d", 0 }, + {} +}; +MODULE_DEVICE_TABLE(i2c, lt7911d_i2c_table); - for (i = 0; i < lt7911d->gpios->ndescs; i++) - gpiod_direction_output(lt7911d->gpios->desc[i], 1); - msleep(20); -} - -static const struct of_device_id lt7911d_fb_notifier_of_match[] = { +static const struct of_device_id lt7911d_of_match[] = { { .compatible = "lontium,lt7911d-fb-notifier" }, {} }; -MODULE_DEVICE_TABLE(of, lt7911d_fb_notifier_of_match); +MODULE_DEVICE_TABLE(of, lt7911d_of_match); -static struct platform_driver lt7911d_fb_notifier_driver = { +static struct i2c_driver lt7911d_i2c_driver = { .driver = { - .name = "lt7911d-fb-notifier", - .of_match_table = lt7911d_fb_notifier_of_match, + .name = "lt7911d", + .of_match_table = lt7911d_of_match, }, - .probe = lt7911d_fb_notifier_probe, - .remove = lt7911d_fb_notifier_remove, - .shutdown = lt7911d_fb_notifier_shutdown, + .probe = lt7911d_i2c_probe, + .remove = lt7911d_i2c_remove, + .shutdown = lt7911d_i2c_shutdown, + .id_table = lt7911d_i2c_table, }; -module_platform_driver(lt7911d_fb_notifier_driver); +static int __init lt7911d_i2c_driver_init(void) +{ + i2c_add_driver(<7911d_i2c_driver); -MODULE_DESCRIPTION("Lontium LT7911D FB Notifier"); + return 0; +} +subsys_initcall_sync(lt7911d_i2c_driver_init); + +static void __exit lt7911d_i2c_driver_exit(void) +{ + i2c_del_driver(<7911d_i2c_driver); +} +module_exit(lt7911d_i2c_driver_exit); + +MODULE_DESCRIPTION("Lontium lt7911dD driver"); MODULE_LICENSE("GPL"); -- Gitblit v1.6.2