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, &lt7911d_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(&lt7911d->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(&lt7911d_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(&lt7911d_i2c_driver);
+}
+module_exit(lt7911d_i2c_driver_exit);
+
+MODULE_DESCRIPTION("Lontium lt7911dD driver");
 MODULE_LICENSE("GPL");

--
Gitblit v1.6.2