xref: /OK3568_Linux_fs/kernel/drivers/misc/lt7911d-fb-notifier.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0+
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Copyright (C) 2023 Rockchip Electronics Co. Ltd.
4*4882a593Smuzhiyun  */
5*4882a593Smuzhiyun 
6*4882a593Smuzhiyun #include <linux/kernel.h>
7*4882a593Smuzhiyun #include <linux/delay.h>
8*4882a593Smuzhiyun #include <linux/i2c.h>
9*4882a593Smuzhiyun #include <linux/platform_device.h>
10*4882a593Smuzhiyun #include <linux/regulator/consumer.h>
11*4882a593Smuzhiyun #include <linux/gpio/consumer.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/of.h>
14*4882a593Smuzhiyun #include <linux/of_gpio.h>
15*4882a593Smuzhiyun #include <linux/notifier.h>
16*4882a593Smuzhiyun #include <linux/fb.h>
17*4882a593Smuzhiyun #include <linux/regmap.h>
18*4882a593Smuzhiyun #include <linux/clk.h>
19*4882a593Smuzhiyun #include "lt7911d-fw.h"
20*4882a593Smuzhiyun 
21*4882a593Smuzhiyun struct lt7911d {
22*4882a593Smuzhiyun 	struct device *dev;
23*4882a593Smuzhiyun 	struct regmap *regmap;
24*4882a593Smuzhiyun 	struct serdes_init_seq *serdes_init_seq;
25*4882a593Smuzhiyun 	struct gpio_desc *reset_gpio;
26*4882a593Smuzhiyun 	struct gpio_desc *enable_gpio;
27*4882a593Smuzhiyun 	struct notifier_block fb_notif;
28*4882a593Smuzhiyun 	int fb_blank;
29*4882a593Smuzhiyun };
30*4882a593Smuzhiyun 
31*4882a593Smuzhiyun static int Datalen = 17594;
32*4882a593Smuzhiyun /*to save hdcp key */
33*4882a593Smuzhiyun static unsigned char HdcpKey[286];
34*4882a593Smuzhiyun /*the buffer to read flash, its size should be equal the size of bin, max size is 24KB*/
35*4882a593Smuzhiyun static unsigned char ReadFirmware[17594];
36*4882a593Smuzhiyun /*The buffer to read flash, hex->bin->txt*/
37*4882a593Smuzhiyun //static unsigned char FirmwareData[17594];
38*4882a593Smuzhiyun 
I2C_Write_Byte(struct lt7911d * lt7911d,unsigned char reg,unsigned char val)39*4882a593Smuzhiyun static int I2C_Write_Byte(struct lt7911d *lt7911d, unsigned char reg, unsigned char val)
40*4882a593Smuzhiyun {
41*4882a593Smuzhiyun 	int ret;
42*4882a593Smuzhiyun 
43*4882a593Smuzhiyun 	ret = regmap_write(lt7911d->regmap, reg, val);
44*4882a593Smuzhiyun 	if (ret < 0) {
45*4882a593Smuzhiyun 		pr_info("failed to write lt7911d register 0x%x: %d\n", reg, ret);
46*4882a593Smuzhiyun 		return ret;
47*4882a593Smuzhiyun 	}
48*4882a593Smuzhiyun 	return 0;
49*4882a593Smuzhiyun }
50*4882a593Smuzhiyun 
I2C_Read_Byte(struct lt7911d * lt7911d,unsigned char reg)51*4882a593Smuzhiyun static unsigned char I2C_Read_Byte(struct lt7911d *lt7911d, unsigned char reg)
52*4882a593Smuzhiyun {
53*4882a593Smuzhiyun 	int ret;
54*4882a593Smuzhiyun 	unsigned int val;
55*4882a593Smuzhiyun 
56*4882a593Smuzhiyun 	ret = regmap_read(lt7911d->regmap, reg, &val);
57*4882a593Smuzhiyun 	if (ret < 0) {
58*4882a593Smuzhiyun 		pr_info("failed to read lt7911d register 0x%x: %d\n", reg, ret);
59*4882a593Smuzhiyun 		return ret;
60*4882a593Smuzhiyun 	}
61*4882a593Smuzhiyun 
62*4882a593Smuzhiyun 	return (unsigned char)val;
63*4882a593Smuzhiyun }
64*4882a593Smuzhiyun 
lt7911d_check_chip_id(struct lt7911d * lt7911d)65*4882a593Smuzhiyun static bool lt7911d_check_chip_id(struct lt7911d *lt7911d)
66*4882a593Smuzhiyun {
67*4882a593Smuzhiyun 	unsigned char id_h, id_l;
68*4882a593Smuzhiyun 
69*4882a593Smuzhiyun 	/*0x80ee=0x01 to enable i2c interface*/
70*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
71*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
72*4882a593Smuzhiyun 	/*write bank 0xa0, read 0xa000 and 0xa001*/
73*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0xA0);
74*4882a593Smuzhiyun 	id_h = I2C_Read_Byte(lt7911d, 0x00);
75*4882a593Smuzhiyun 	id_l = I2C_Read_Byte(lt7911d, 0x01);
76*4882a593Smuzhiyun 
77*4882a593Smuzhiyun 	/*chip id=0x1605*/
78*4882a593Smuzhiyun 	if ((id_h == 0x16) && (id_l == 0x05)) {
79*4882a593Smuzhiyun 		pr_info("%s chip id =0x1605\n", __func__);
80*4882a593Smuzhiyun 		/*0x80ee=0x00 to disable i2c*/
81*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xFF, 0x80);
82*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xEE, 0x00);
83*4882a593Smuzhiyun 		return true;
84*4882a593Smuzhiyun 	} else {
85*4882a593Smuzhiyun 		pr_info("%s chip id 0x%x is not 0x1605\n", __func__, (id_h << 8) | id_l);
86*4882a593Smuzhiyun 		/*0x80ee=0x00 to disable i2c*/
87*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xFF, 0x80);
88*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xEE, 0x00);
89*4882a593Smuzhiyun 		return false;
90*4882a593Smuzhiyun 	}
91*4882a593Smuzhiyun }
92*4882a593Smuzhiyun 
lt7911d_check_fw_version(struct lt7911d * lt7911d)93*4882a593Smuzhiyun static int lt7911d_check_fw_version(struct lt7911d *lt7911d)
94*4882a593Smuzhiyun {
95*4882a593Smuzhiyun 	unsigned char fw;
96*4882a593Smuzhiyun 
97*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
98*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
99*4882a593Smuzhiyun 
100*4882a593Smuzhiyun 	/*read 0xD211*/
101*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0xD2);
102*4882a593Smuzhiyun 	fw = I2C_Read_Byte(lt7911d, 0x11);
103*4882a593Smuzhiyun 
104*4882a593Smuzhiyun 	/*fw version address is 0x1dfb*/
105*4882a593Smuzhiyun 	if (fw < FirmwareData[0x1dfb]) {
106*4882a593Smuzhiyun 		pr_info("%s fw %d<%d, need to upgrade\n", __func__, fw, FirmwareData[0x1dfb]);
107*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xFF, 0x80);
108*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xEE, 0x00);
109*4882a593Smuzhiyun 		return 0;
110*4882a593Smuzhiyun 	} else {
111*4882a593Smuzhiyun 		pr_info("%s fw %d>=%d, no need upgrade\n", __func__, fw, FirmwareData[0x1dfb]);
112*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xFF, 0x80);
113*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0xEE, 0x00);
114*4882a593Smuzhiyun 		return -1;
115*4882a593Smuzhiyun 	}
116*4882a593Smuzhiyun }
117*4882a593Smuzhiyun 
lt7911d_config_para(struct lt7911d * lt7911d)118*4882a593Smuzhiyun static void lt7911d_config_para(struct lt7911d *lt7911d)
119*4882a593Smuzhiyun {
120*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
121*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
122*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5A, 0x82);
123*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5E, 0xC0);
124*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x58, 0x00);
125*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x59, 0x51);
126*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5A, 0x92);
127*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5A, 0x82);
128*4882a593Smuzhiyun }
129*4882a593Smuzhiyun 
lt7911d_block_erase(struct lt7911d * lt7911d)130*4882a593Smuzhiyun static void lt7911d_block_erase(struct lt7911d *lt7911d)
131*4882a593Smuzhiyun {
132*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
133*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
134*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5A, 0x86);
135*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5A, 0x82);
136*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5B, 0x00);
137*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5C, 0x00);
138*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5D, 0x00);
139*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5A, 0x83);
140*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5A, 0x82);
141*4882a593Smuzhiyun 
142*4882a593Smuzhiyun 	/*The time to waiting for earse flash*/
143*4882a593Smuzhiyun 	msleep(500);
144*4882a593Smuzhiyun }
145*4882a593Smuzhiyun 
146*4882a593Smuzhiyun /*If earse flash will erase the hdcp key, so need to backup firstly*/
SaveHdcpKeyFromFlash(struct lt7911d * lt7911d)147*4882a593Smuzhiyun static void SaveHdcpKeyFromFlash(struct lt7911d *lt7911d)
148*4882a593Smuzhiyun {
149*4882a593Smuzhiyun 	unsigned int StartAddr;
150*4882a593Smuzhiyun 	unsigned int npage, i, j;
151*4882a593Smuzhiyun 	unsigned char npagelen = 0;
152*4882a593Smuzhiyun 	unsigned char addr[3] = {0};
153*4882a593Smuzhiyun 
154*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
155*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
156*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x90);
157*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xdf);
158*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xff);
159*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
160*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x86);
161*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
162*4882a593Smuzhiyun 
163*4882a593Smuzhiyun 	/*The first address of HDCP KEY*/
164*4882a593Smuzhiyun 	StartAddr = 0x006000;
165*4882a593Smuzhiyun 	addr[0] = (StartAddr & 0xFF0000) >> 16;
166*4882a593Smuzhiyun 	addr[1] = (StartAddr & 0xFF00) >> 8;
167*4882a593Smuzhiyun 	addr[2] = StartAddr & 0xFF;
168*4882a593Smuzhiyun 
169*4882a593Smuzhiyun 	/*hdcp key size is 286 byte*/
170*4882a593Smuzhiyun 	npage = 18;
171*4882a593Smuzhiyun 	npagelen = 16;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	for (i = 0; i < npage; i++) {
174*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5E, 0x6f);
175*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0xA2);
176*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
177*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5B, addr[0]);
178*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5C, addr[1]);
179*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5D, addr[2]);
180*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x92);
181*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
182*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x58, 0x01);
183*4882a593Smuzhiyun 
184*4882a593Smuzhiyun 		if (i == 17)
185*4882a593Smuzhiyun 			npagelen = 14;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		for (j = 0; j < npagelen; j++)
188*4882a593Smuzhiyun 			HdcpKey[i * 16 + j] = I2C_Read_Byte(lt7911d, 0x5F);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 		StartAddr += 16;
191*4882a593Smuzhiyun 		addr[0] = (StartAddr & 0xFF0000) >> 16;
192*4882a593Smuzhiyun 		addr[1] = (StartAddr & 0xFF00) >> 8;
193*4882a593Smuzhiyun 		addr[2] = StartAddr & 0xFF;
194*4882a593Smuzhiyun 	}
195*4882a593Smuzhiyun 
196*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x8a);
197*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun 
lt7911d_write_firmware_to_flash(struct lt7911d * lt7911d)200*4882a593Smuzhiyun static void lt7911d_write_firmware_to_flash(struct lt7911d *lt7911d)
201*4882a593Smuzhiyun {
202*4882a593Smuzhiyun 	unsigned int StartAddr;
203*4882a593Smuzhiyun 	unsigned int npage, i, j;
204*4882a593Smuzhiyun 	unsigned char npagelen = 0;
205*4882a593Smuzhiyun 	unsigned char addr[3] = {0};
206*4882a593Smuzhiyun 
207*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
208*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
209*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x90);
210*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xdf);
211*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xff);
212*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
213*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x86);
214*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	/*The first address of flash��Max Size 24K*/
217*4882a593Smuzhiyun 	StartAddr = 0x000000;
218*4882a593Smuzhiyun 	addr[0] = (StartAddr & 0xFF0000) >> 16;
219*4882a593Smuzhiyun 	addr[1] = (StartAddr & 0xFF00) >> 8;
220*4882a593Smuzhiyun 	addr[2] = StartAddr & 0xFF;
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	if (Datalen % 16) {
223*4882a593Smuzhiyun 		/*Datalen is the length of the firmware.*/
224*4882a593Smuzhiyun 		npage = Datalen / 16 + 1;
225*4882a593Smuzhiyun 	} else {
226*4882a593Smuzhiyun 		npage = Datalen / 16;
227*4882a593Smuzhiyun 	}
228*4882a593Smuzhiyun 	npagelen = 16;
229*4882a593Smuzhiyun 
230*4882a593Smuzhiyun 	for (i = 0; i < npage; i++) {
231*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x86);
232*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
233*4882a593Smuzhiyun 
234*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5E, 0xef);
235*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0xA2);
236*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
237*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x58, 0x01);
238*4882a593Smuzhiyun 
239*4882a593Smuzhiyun 		if ((Datalen - i * 16) < 16)
240*4882a593Smuzhiyun 			npagelen = Datalen - i*16;
241*4882a593Smuzhiyun 
242*4882a593Smuzhiyun 		for (j = 0; j < npagelen; j++) {
243*4882a593Smuzhiyun 			/*please just continue to write data to 0x59,*/
244*4882a593Smuzhiyun 			/*and lt7911d will increase the address auto use 0xff*/
245*4882a593Smuzhiyun 			/*as insufficient data if datelen%16 is not zero*/
246*4882a593Smuzhiyun 			I2C_Write_Byte(lt7911d, 0x59, FirmwareData[i*16 + j]);
247*4882a593Smuzhiyun 		}
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 		/*change the first address*/
250*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5B, addr[0]);
251*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5C, addr[1]);
252*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5D, addr[2]);
253*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5E, 0xE0);
254*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x92);
255*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
256*4882a593Smuzhiyun 
257*4882a593Smuzhiyun 		StartAddr += 16;
258*4882a593Smuzhiyun 		addr[0] = (StartAddr & 0xFF0000) >> 16;
259*4882a593Smuzhiyun 		addr[1] = (StartAddr & 0xFF00) >> 8;
260*4882a593Smuzhiyun 		addr[2] = StartAddr & 0xFF;
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x8a);
264*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
265*4882a593Smuzhiyun 
266*4882a593Smuzhiyun 	/*reset fifo*/
267*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x90);
268*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xDF);
269*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xFF);
270*4882a593Smuzhiyun 	msleep(20);
271*4882a593Smuzhiyun }
272*4882a593Smuzhiyun 
lt7911d_write_hdcpkey_to_flash(struct lt7911d * lt7911d)273*4882a593Smuzhiyun static void lt7911d_write_hdcpkey_to_flash(struct lt7911d *lt7911d)
274*4882a593Smuzhiyun {
275*4882a593Smuzhiyun 	unsigned int StartAddr;
276*4882a593Smuzhiyun 	unsigned int npage, i, j;
277*4882a593Smuzhiyun 	unsigned char npagelen = 0;
278*4882a593Smuzhiyun 	unsigned char addr[3] = {0};
279*4882a593Smuzhiyun 
280*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
281*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
282*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x90);
283*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xdf);
284*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xff);
285*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
286*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x86);
287*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
288*4882a593Smuzhiyun 
289*4882a593Smuzhiyun 	/*hdcp key first address*/
290*4882a593Smuzhiyun 	StartAddr = 0x006000;
291*4882a593Smuzhiyun 	addr[0] = (StartAddr & 0xFF0000) >> 16;
292*4882a593Smuzhiyun 	addr[1] = (StartAddr & 0xFF00) >> 8;
293*4882a593Smuzhiyun 	addr[2] = StartAddr & 0xFF;
294*4882a593Smuzhiyun 
295*4882a593Smuzhiyun 	npage = 18;
296*4882a593Smuzhiyun 	npagelen = 16;
297*4882a593Smuzhiyun 
298*4882a593Smuzhiyun 	for (i = 0; i < npage; i++) {
299*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x86);
300*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
301*4882a593Smuzhiyun 
302*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5E, 0xef);
303*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0xA2);
304*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
305*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x58, 0x01);
306*4882a593Smuzhiyun 
307*4882a593Smuzhiyun 		if (i == 17)
308*4882a593Smuzhiyun 			npagelen = 14;
309*4882a593Smuzhiyun 
310*4882a593Smuzhiyun 		for (j = 0; j < npagelen; j++) {
311*4882a593Smuzhiyun 			/*please just continue to write data to 0x59,*/
312*4882a593Smuzhiyun 			/*and lt7911d will increase the address auto use 0xff*/
313*4882a593Smuzhiyun 			/*as insufficient data if datelen%16 is not zero .*/
314*4882a593Smuzhiyun 			I2C_Write_Byte(lt7911d, 0x59, HdcpKey[i*16 + j]);
315*4882a593Smuzhiyun 		}
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun 		if (npagelen == 14) {
318*4882a593Smuzhiyun 			I2C_Write_Byte(lt7911d, 0x59, 0xFF);
319*4882a593Smuzhiyun 			I2C_Write_Byte(lt7911d, 0x59, 0xFF);
320*4882a593Smuzhiyun 		}
321*4882a593Smuzhiyun 
322*4882a593Smuzhiyun 		/*change the first address*/
323*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5B, addr[0]);
324*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5C, addr[1]);
325*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5D, addr[2]);
326*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5E, 0xE0);
327*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x92);
328*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
329*4882a593Smuzhiyun 
330*4882a593Smuzhiyun 		StartAddr += 16;
331*4882a593Smuzhiyun 		addr[0] = (StartAddr & 0xFF0000) >> 16;
332*4882a593Smuzhiyun 		addr[1] = (StartAddr & 0xFF00) >> 8;
333*4882a593Smuzhiyun 		addr[2] = StartAddr & 0xFF;
334*4882a593Smuzhiyun 	}
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x8a);
337*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	/*reset fifo*/
340*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x90);
341*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xDF);
342*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xFF);
343*4882a593Smuzhiyun 	msleep(20);
344*4882a593Smuzhiyun }
345*4882a593Smuzhiyun 
lt7911d_read_firmware_from_flash(struct lt7911d * lt7911d)346*4882a593Smuzhiyun static void lt7911d_read_firmware_from_flash(struct lt7911d *lt7911d)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun 	unsigned int StartAddr;
349*4882a593Smuzhiyun 	unsigned int npage, i, j;
350*4882a593Smuzhiyun 	unsigned char npagelen = 0;
351*4882a593Smuzhiyun 	unsigned char addr[3] = {0};
352*4882a593Smuzhiyun 
353*4882a593Smuzhiyun 	memset(ReadFirmware, 0, sizeof(ReadFirmware));
354*4882a593Smuzhiyun 
355*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
356*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x01);
357*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x90);
358*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xdf);
359*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x02, 0xff);
360*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
361*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x86);
362*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
363*4882a593Smuzhiyun 
364*4882a593Smuzhiyun 	/*the first address of firmware*/
365*4882a593Smuzhiyun 	StartAddr = 0x000000;
366*4882a593Smuzhiyun 	addr[0] = (StartAddr & 0xFF0000) >> 16;
367*4882a593Smuzhiyun 	addr[1] = (StartAddr & 0xFF00) >> 8;
368*4882a593Smuzhiyun 	addr[2] = StartAddr & 0xFF;
369*4882a593Smuzhiyun 
370*4882a593Smuzhiyun 	if (Datalen % 16)
371*4882a593Smuzhiyun 		npage = Datalen / 16 + 1;
372*4882a593Smuzhiyun 	else
373*4882a593Smuzhiyun 		npage = Datalen / 16;
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun 	npagelen = 16;
376*4882a593Smuzhiyun 
377*4882a593Smuzhiyun 	for (i = 0; i < npage; i++) {
378*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5E, 0x6f);
379*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0xA2);
380*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
381*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5B, addr[0]);
382*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5C, addr[1]);
383*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5D, addr[2]);
384*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x92);
385*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x5A, 0x82);
386*4882a593Smuzhiyun 		I2C_Write_Byte(lt7911d, 0x58, 0x01);
387*4882a593Smuzhiyun 
388*4882a593Smuzhiyun 		if ((Datalen - i * 16) < 16)
389*4882a593Smuzhiyun 			npagelen = Datalen - i*16;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 		for (j = 0; j < npagelen; j++) {
392*4882a593Smuzhiyun 			/*please just continue to read data from 0x5f*/
393*4882a593Smuzhiyun 			/*lt7911d will increase the address auto*/
394*4882a593Smuzhiyun 			ReadFirmware[i*16 + j] = I2C_Read_Byte(lt7911d, 0x5F);
395*4882a593Smuzhiyun 		}
396*4882a593Smuzhiyun 
397*4882a593Smuzhiyun 		StartAddr += 16;
398*4882a593Smuzhiyun 		/*change the first address*/
399*4882a593Smuzhiyun 		addr[0] = (StartAddr & 0xFF0000) >> 16;
400*4882a593Smuzhiyun 		addr[1] = (StartAddr & 0xFF00) >> 8;
401*4882a593Smuzhiyun 		addr[2] = StartAddr & 0xFF;
402*4882a593Smuzhiyun 	}
403*4882a593Smuzhiyun 
404*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x8a);
405*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0x5a, 0x82);
406*4882a593Smuzhiyun }
407*4882a593Smuzhiyun 
lt7911_compare_firmware(struct lt7911d * lt7911d)408*4882a593Smuzhiyun static int lt7911_compare_firmware(struct lt7911d *lt7911d)
409*4882a593Smuzhiyun {
410*4882a593Smuzhiyun 	unsigned int len;
411*4882a593Smuzhiyun 
412*4882a593Smuzhiyun 	for (len = 0; len < Datalen; len++) {
413*4882a593Smuzhiyun 		if (ReadFirmware[len] != FirmwareData[len]) {
414*4882a593Smuzhiyun 			pr_info("%s: ReadFirmware[%d] 0x%x !=  0x%x FirmwareData[%d]\n",
415*4882a593Smuzhiyun 					__func__, len, ReadFirmware[len], FirmwareData[len], len);
416*4882a593Smuzhiyun 			return -1;
417*4882a593Smuzhiyun 		}
418*4882a593Smuzhiyun 	}
419*4882a593Smuzhiyun 	return 0;
420*4882a593Smuzhiyun }
421*4882a593Smuzhiyun 
lt7911d_firmware_upgrade(struct lt7911d * lt7911d)422*4882a593Smuzhiyun static int lt7911d_firmware_upgrade(struct lt7911d *lt7911d)
423*4882a593Smuzhiyun {
424*4882a593Smuzhiyun 	int ret = 0;
425*4882a593Smuzhiyun 
426*4882a593Smuzhiyun 	if (lt7911d_check_chip_id(lt7911d)) {
427*4882a593Smuzhiyun 		if (lt7911d_check_fw_version(lt7911d) == 0) {
428*4882a593Smuzhiyun 			lt7911d_config_para(lt7911d);
429*4882a593Smuzhiyun 			SaveHdcpKeyFromFlash(lt7911d);
430*4882a593Smuzhiyun 			lt7911d_block_erase(lt7911d);
431*4882a593Smuzhiyun 			lt7911d_write_firmware_to_flash(lt7911d);
432*4882a593Smuzhiyun 			lt7911d_write_hdcpkey_to_flash(lt7911d);
433*4882a593Smuzhiyun 			lt7911d_read_firmware_from_flash(lt7911d);
434*4882a593Smuzhiyun 
435*4882a593Smuzhiyun 			if (!lt7911_compare_firmware(lt7911d)) {
436*4882a593Smuzhiyun 				pr_info("%s: upgrade success\n", __func__);
437*4882a593Smuzhiyun 				ret = 0;
438*4882a593Smuzhiyun 			} else {
439*4882a593Smuzhiyun 				pr_info("%s: upgrade Fail\n", __func__);
440*4882a593Smuzhiyun 				ret = -1;
441*4882a593Smuzhiyun 			}
442*4882a593Smuzhiyun 		}
443*4882a593Smuzhiyun 	} else {
444*4882a593Smuzhiyun 		pr_info("the chip lt7911d is offline\n");
445*4882a593Smuzhiyun 		ret = 0;
446*4882a593Smuzhiyun 	}
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xFF, 0x80);
449*4882a593Smuzhiyun 	I2C_Write_Byte(lt7911d, 0xEE, 0x00);
450*4882a593Smuzhiyun 
451*4882a593Smuzhiyun 	return ret;
452*4882a593Smuzhiyun }
453*4882a593Smuzhiyun 
454*4882a593Smuzhiyun static const struct regmap_config lt7911d_regmap_config = {
455*4882a593Smuzhiyun 	.name = "lt7911d",
456*4882a593Smuzhiyun 	.reg_bits = 8,
457*4882a593Smuzhiyun 	.val_bits = 8,
458*4882a593Smuzhiyun 	.max_register = 0x100,
459*4882a593Smuzhiyun };
460*4882a593Smuzhiyun 
lt7911d_fb_notifier_callback(struct notifier_block * self,unsigned long event,void * data)461*4882a593Smuzhiyun static int lt7911d_fb_notifier_callback(struct notifier_block *self,
462*4882a593Smuzhiyun 					unsigned long event, void *data)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun 	struct lt7911d *lt7911d = container_of(self, struct lt7911d, fb_notif);
465*4882a593Smuzhiyun 	struct fb_event *evdata = data;
466*4882a593Smuzhiyun 	int fb_blank = *(int *)evdata->data;
467*4882a593Smuzhiyun 
468*4882a593Smuzhiyun 	if (event != FB_EVENT_BLANK)
469*4882a593Smuzhiyun 		return 0;
470*4882a593Smuzhiyun 
471*4882a593Smuzhiyun 	if (lt7911d->fb_blank == fb_blank)
472*4882a593Smuzhiyun 		return 0;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	if (fb_blank == FB_BLANK_UNBLANK) {
475*4882a593Smuzhiyun 		if (lt7911d->reset_gpio) {
476*4882a593Smuzhiyun 			gpiod_direction_output(lt7911d->reset_gpio, 1);
477*4882a593Smuzhiyun 			msleep(20);
478*4882a593Smuzhiyun 			gpiod_direction_output(lt7911d->reset_gpio, 0);
479*4882a593Smuzhiyun 			msleep(400);
480*4882a593Smuzhiyun 		}
481*4882a593Smuzhiyun 	}
482*4882a593Smuzhiyun 
483*4882a593Smuzhiyun 	lt7911d->fb_blank = fb_blank;
484*4882a593Smuzhiyun 
485*4882a593Smuzhiyun 	return 0;
486*4882a593Smuzhiyun }
487*4882a593Smuzhiyun 
lt7911d_i2c_probe(struct i2c_client * client,const struct i2c_device_id * id)488*4882a593Smuzhiyun static int lt7911d_i2c_probe(struct i2c_client *client,
489*4882a593Smuzhiyun 			      const struct i2c_device_id *id)
490*4882a593Smuzhiyun {
491*4882a593Smuzhiyun 	struct device *dev = &client->dev;
492*4882a593Smuzhiyun 	struct lt7911d *lt7911d;
493*4882a593Smuzhiyun 	int ret = 0, i = 0;
494*4882a593Smuzhiyun 
495*4882a593Smuzhiyun 	lt7911d = devm_kzalloc(dev, sizeof(*lt7911d), GFP_KERNEL);
496*4882a593Smuzhiyun 	if (!lt7911d)
497*4882a593Smuzhiyun 		return -ENOMEM;
498*4882a593Smuzhiyun 
499*4882a593Smuzhiyun 	lt7911d->dev = dev;
500*4882a593Smuzhiyun 	i2c_set_clientdata(client, lt7911d);
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun 	lt7911d->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW);
503*4882a593Smuzhiyun 	if (IS_ERR(lt7911d->reset_gpio))
504*4882a593Smuzhiyun 		return dev_err_probe(dev, PTR_ERR(lt7911d->reset_gpio),
505*4882a593Smuzhiyun 				     "failed to acquire reset gpio\n");
506*4882a593Smuzhiyun 
507*4882a593Smuzhiyun 	gpiod_set_consumer_name(lt7911d->reset_gpio, "lt7911d-reset");
508*4882a593Smuzhiyun 
509*4882a593Smuzhiyun 	lt7911d->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_LOW);
510*4882a593Smuzhiyun 	if (IS_ERR(lt7911d->enable_gpio))
511*4882a593Smuzhiyun 		return dev_err_probe(dev, PTR_ERR(lt7911d->enable_gpio),
512*4882a593Smuzhiyun 				     "failed to acquire enable gpio\n");
513*4882a593Smuzhiyun 
514*4882a593Smuzhiyun 	lt7911d->regmap = devm_regmap_init_i2c(client, &lt7911d_regmap_config);
515*4882a593Smuzhiyun 	if (IS_ERR(lt7911d->regmap))
516*4882a593Smuzhiyun 		return dev_err_probe(dev, PTR_ERR(lt7911d->regmap),
517*4882a593Smuzhiyun 				     "failed to initialize regmap\n");
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun 	lt7911d->fb_blank = FB_BLANK_UNBLANK;
520*4882a593Smuzhiyun 	lt7911d->fb_notif.notifier_call = lt7911d_fb_notifier_callback;
521*4882a593Smuzhiyun 	ret = fb_register_client(&lt7911d->fb_notif);
522*4882a593Smuzhiyun 	if (ret)
523*4882a593Smuzhiyun 		return dev_err_probe(dev, ret, "failed to register fb client\n");
524*4882a593Smuzhiyun 
525*4882a593Smuzhiyun 	for (i = 0; i < 3; i++) {
526*4882a593Smuzhiyun 		if (!lt7911d_firmware_upgrade(lt7911d))
527*4882a593Smuzhiyun 			break;
528*4882a593Smuzhiyun 	}
529*4882a593Smuzhiyun 
530*4882a593Smuzhiyun 	dev_info(dev, "%s end\n", __func__);
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	return 0;
533*4882a593Smuzhiyun }
534*4882a593Smuzhiyun 
lt7911d_i2c_shutdown(struct i2c_client * client)535*4882a593Smuzhiyun static void lt7911d_i2c_shutdown(struct i2c_client *client)
536*4882a593Smuzhiyun {
537*4882a593Smuzhiyun 	struct lt7911d *lt7911d = i2c_get_clientdata(client);
538*4882a593Smuzhiyun 
539*4882a593Smuzhiyun 	gpiod_direction_output(lt7911d->reset_gpio, 1);
540*4882a593Smuzhiyun 	msleep(20);
541*4882a593Smuzhiyun }
542*4882a593Smuzhiyun 
lt7911d_i2c_remove(struct i2c_client * client)543*4882a593Smuzhiyun static int lt7911d_i2c_remove(struct i2c_client *client)
544*4882a593Smuzhiyun {
545*4882a593Smuzhiyun 	struct lt7911d *lt7911d = i2c_get_clientdata(client);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	fb_unregister_client(&lt7911d->fb_notif);
548*4882a593Smuzhiyun 
549*4882a593Smuzhiyun 	return 0;
550*4882a593Smuzhiyun }
551*4882a593Smuzhiyun 
552*4882a593Smuzhiyun static const struct i2c_device_id lt7911d_i2c_table[] = {
553*4882a593Smuzhiyun 	{ "lt7911d", 0 },
554*4882a593Smuzhiyun 	{}
555*4882a593Smuzhiyun };
556*4882a593Smuzhiyun MODULE_DEVICE_TABLE(i2c, lt7911d_i2c_table);
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun static const struct of_device_id lt7911d_of_match[] = {
559*4882a593Smuzhiyun 	{ .compatible = "lontium,lt7911d-fb-notifier" },
560*4882a593Smuzhiyun 	{}
561*4882a593Smuzhiyun };
562*4882a593Smuzhiyun MODULE_DEVICE_TABLE(of, lt7911d_of_match);
563*4882a593Smuzhiyun 
564*4882a593Smuzhiyun static struct i2c_driver lt7911d_i2c_driver = {
565*4882a593Smuzhiyun 	.driver = {
566*4882a593Smuzhiyun 		.name = "lt7911d",
567*4882a593Smuzhiyun 		.of_match_table = lt7911d_of_match,
568*4882a593Smuzhiyun 	},
569*4882a593Smuzhiyun 	.probe = lt7911d_i2c_probe,
570*4882a593Smuzhiyun 	.remove = lt7911d_i2c_remove,
571*4882a593Smuzhiyun 	.shutdown = lt7911d_i2c_shutdown,
572*4882a593Smuzhiyun 	.id_table = lt7911d_i2c_table,
573*4882a593Smuzhiyun };
574*4882a593Smuzhiyun 
lt7911d_i2c_driver_init(void)575*4882a593Smuzhiyun static int __init lt7911d_i2c_driver_init(void)
576*4882a593Smuzhiyun {
577*4882a593Smuzhiyun 	i2c_add_driver(&lt7911d_i2c_driver);
578*4882a593Smuzhiyun 
579*4882a593Smuzhiyun 	return 0;
580*4882a593Smuzhiyun }
581*4882a593Smuzhiyun subsys_initcall_sync(lt7911d_i2c_driver_init);
582*4882a593Smuzhiyun 
lt7911d_i2c_driver_exit(void)583*4882a593Smuzhiyun static void __exit lt7911d_i2c_driver_exit(void)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun 	i2c_del_driver(&lt7911d_i2c_driver);
586*4882a593Smuzhiyun }
587*4882a593Smuzhiyun module_exit(lt7911d_i2c_driver_exit);
588*4882a593Smuzhiyun 
589*4882a593Smuzhiyun MODULE_DESCRIPTION("Lontium lt7911dD driver");
590*4882a593Smuzhiyun MODULE_LICENSE("GPL");
591