xref: /linux/drivers/gpu/drm/bridge/lontium-lt8713sx.c (revision fbf5df34a4dbcd09d433dd4f0916bf9b2ddb16de)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
4  */
5 
6 #include <linux/crc8.h>
7 #include <linux/firmware.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/i2c.h>
10 #include <linux/interrupt.h>
11 #include <linux/module.h>
12 #include <linux/mutex.h>
13 #include <linux/of_graph.h>
14 #include <linux/platform_device.h>
15 #include <linux/regmap.h>
16 #include <linux/regulator/consumer.h>
17 #include <linux/sizes.h>
18 #include <linux/wait.h>
19 #include <linux/workqueue.h>
20 
21 #include <drm/drm_bridge.h>
22 #include <drm/drm_of.h>
23 
24 #define FW_FILE "lt8713sx_fw.bin"
25 
26 #define REG_PAGE_CONTROL	0xff
27 
28 #define LT8713SX_PAGE_SIZE	256
29 
30 DECLARE_CRC8_TABLE(lt8713sx_crc_table);
31 
32 struct lt8713sx {
33 	struct device *dev;
34 	struct drm_bridge bridge;
35 	struct drm_bridge *next_bridge;
36 
37 	struct regmap *regmap;
38 	/* Protects all accesses to registers by stopping the on-chip MCU */
39 	struct mutex ocm_lock;
40 
41 	struct gpio_desc *reset_gpio;
42 	struct gpio_desc *enable_gpio;
43 
44 	struct i2c_client *client;
45 	const struct firmware *fw;
46 
47 	u8 *fw_buffer;
48 
49 	u32 main_crc_value;
50 	u32 bank_crc_value[17];
51 
52 	int bank_num;
53 };
54 
55 static void lt8713sx_reset(struct lt8713sx *lt8713sx);
56 
57 static const struct regmap_range lt8713sx_ranges[] = {
58 	{
59 		.range_min = 0x0000,
60 		.range_max = 0xffff
61 	},
62 };
63 
64 static const struct regmap_access_table lt8713sx_table = {
65 	.yes_ranges = lt8713sx_ranges,
66 	.n_yes_ranges = ARRAY_SIZE(lt8713sx_ranges),
67 };
68 
69 static const struct regmap_range_cfg lt8713sx_range_cfg = {
70 	.name = "lt8713sx",
71 	.range_min = 0x0000,
72 	.range_max = 0xffff,
73 	.selector_reg = REG_PAGE_CONTROL,
74 	.selector_mask = 0xff,
75 	.selector_shift = 0,
76 	.window_start = 0,
77 	.window_len = 0x100,
78 };
79 
80 static const struct regmap_config lt8713sx_regmap_config = {
81 	.reg_bits = 8,
82 	.val_bits = 8,
83 	.volatile_table = &lt8713sx_table,
84 	.ranges = &lt8713sx_range_cfg,
85 	.num_ranges = 1,
86 	.cache_type = REGCACHE_NONE,
87 	.max_register = 0xffff,
88 };
89 
90 static void lt8713sx_i2c_enable(struct lt8713sx *lt8713sx)
91 {
92 	regmap_write(lt8713sx->regmap, 0xe0ee, 0x01);
93 }
94 
95 static void lt8713sx_i2c_disable(struct lt8713sx *lt8713sx)
96 {
97 	regmap_write(lt8713sx->regmap, 0xe0ee, 0x00);
98 }
99 
100 static int lt8713sx_prepare_firmware_data(struct lt8713sx *lt8713sx)
101 {
102 	int ret = 0;
103 	size_t sz_12k = 12 * SZ_1K;
104 
105 	ret = request_firmware(&lt8713sx->fw, FW_FILE, lt8713sx->dev);
106 	if (ret < 0) {
107 		dev_err(lt8713sx->dev, "request firmware failed\n");
108 		return ret;
109 	}
110 
111 	dev_dbg(lt8713sx->dev, "Firmware size: %zu bytes\n", lt8713sx->fw->size);
112 
113 	if (lt8713sx->fw->size > SZ_256K - 1) {
114 		dev_err(lt8713sx->dev, "Firmware size exceeds 256KB limit\n");
115 		release_firmware(lt8713sx->fw);
116 		return -EINVAL;
117 	}
118 
119 	lt8713sx->fw_buffer = kvmalloc(SZ_256K, GFP_KERNEL);
120 	if (!lt8713sx->fw_buffer) {
121 		release_firmware(lt8713sx->fw);
122 		return -ENOMEM;
123 	}
124 
125 	memset(lt8713sx->fw_buffer, 0xff, SZ_256K);
126 
127 	/* main firmware */
128 	memcpy(lt8713sx->fw_buffer, lt8713sx->fw->data, SZ_64K - 1);
129 
130 	lt8713sx->fw_buffer[SZ_64K - 1] =
131 		crc8(lt8713sx_crc_table, lt8713sx->fw_buffer, SZ_64K - 1, 0);
132 	lt8713sx->main_crc_value = lt8713sx->fw_buffer[SZ_64K - 1];
133 	dev_dbg(lt8713sx->dev,
134 		"Main Firmware Data  Crc = 0x%02X\n", lt8713sx->main_crc_value);
135 
136 	/* bank firmware */
137 	memcpy(lt8713sx->fw_buffer + SZ_64K,
138 	       lt8713sx->fw->data + SZ_64K,
139 	       lt8713sx->fw->size - SZ_64K);
140 
141 	lt8713sx->bank_num = (lt8713sx->fw->size - SZ_64K + sz_12k - 1) / sz_12k;
142 	dev_dbg(lt8713sx->dev, "Bank Number Total is %d.\n", lt8713sx->bank_num);
143 
144 	for (int i = 0; i < lt8713sx->bank_num; i++) {
145 		lt8713sx->bank_crc_value[i] =
146 			crc8(lt8713sx_crc_table, lt8713sx->fw_buffer + SZ_64K + i * sz_12k,
147 			     sz_12k, 0);
148 		dev_dbg(lt8713sx->dev, "Bank number:%d; Firmware Data  Crc:0x%02X\n",
149 			i, lt8713sx->bank_crc_value[i]);
150 	}
151 	return 0;
152 }
153 
154 static void lt8713sx_config_parameters(struct lt8713sx *lt8713sx)
155 {
156 	regmap_write(lt8713sx->regmap, 0xe05e, 0xc1);
157 	regmap_write(lt8713sx->regmap, 0xe058, 0x00);
158 	regmap_write(lt8713sx->regmap, 0xe059, 0x50);
159 	regmap_write(lt8713sx->regmap, 0xe05a, 0x10);
160 	regmap_write(lt8713sx->regmap, 0xe05a, 0x00);
161 	regmap_write(lt8713sx->regmap, 0xe058, 0x21);
162 }
163 
164 static void lt8713sx_wren(struct lt8713sx *lt8713sx)
165 {
166 	regmap_write(lt8713sx->regmap, 0xe103, 0xbf);
167 	regmap_write(lt8713sx->regmap, 0xe103, 0xff);
168 	regmap_write(lt8713sx->regmap, 0xe05a, 0x04);
169 	regmap_write(lt8713sx->regmap, 0xe05a, 0x00);
170 }
171 
172 static void lt8713sx_wrdi(struct lt8713sx *lt8713sx)
173 {
174 	regmap_write(lt8713sx->regmap, 0xe05a, 0x08);
175 	regmap_write(lt8713sx->regmap, 0xe05a, 0x00);
176 }
177 
178 static void lt8713sx_fifo_reset(struct lt8713sx *lt8713sx)
179 {
180 	regmap_write(lt8713sx->regmap, 0xe103, 0xbf);
181 	regmap_write(lt8713sx->regmap, 0xe103, 0xff);
182 }
183 
184 static void lt8713sx_disable_sram_write(struct lt8713sx *lt8713sx)
185 {
186 	regmap_write(lt8713sx->regmap, 0xe055, 0x00);
187 }
188 
189 static void lt8713sx_sram_to_flash(struct lt8713sx *lt8713sx)
190 {
191 	regmap_write(lt8713sx->regmap, 0xe05a, 0x30);
192 	regmap_write(lt8713sx->regmap, 0xe05a, 0x00);
193 }
194 
195 static void lt8713sx_i2c_to_sram(struct lt8713sx *lt8713sx)
196 {
197 	regmap_write(lt8713sx->regmap, 0xe055, 0x80);
198 	regmap_write(lt8713sx->regmap, 0xe05e, 0xc0);
199 	regmap_write(lt8713sx->regmap, 0xe058, 0x21);
200 }
201 
202 static u8 lt8713sx_read_flash_status(struct lt8713sx *lt8713sx)
203 {
204 	u32 flash_status = 0;
205 
206 	regmap_write(lt8713sx->regmap,  0xe103, 0x3f);
207 	regmap_write(lt8713sx->regmap,  0xe103, 0xff);
208 
209 	regmap_write(lt8713sx->regmap,  0xe05e, 0x40);
210 	regmap_write(lt8713sx->regmap,  0xe056, 0x05); /* opcode=read status register */
211 	regmap_write(lt8713sx->regmap,  0xe055, 0x25);
212 	regmap_write(lt8713sx->regmap,  0xe055, 0x01);
213 	regmap_write(lt8713sx->regmap,  0xe058, 0x21);
214 
215 	regmap_read(lt8713sx->regmap, 0xe05f, &flash_status);
216 	dev_dbg(lt8713sx->dev, "flash_status:%x\n", flash_status);
217 
218 	return flash_status;
219 }
220 
221 static void lt8713sx_block_erase(struct lt8713sx *lt8713sx)
222 {
223 	u32 i = 0;
224 	u8 flash_status = 0;
225 	u8 blocknum = 0x00;
226 	u32 flashaddr = 0x00;
227 
228 	for (blocknum = 0; blocknum < 8; blocknum++) {
229 		flashaddr = blocknum * SZ_32K;
230 		regmap_write(lt8713sx->regmap,  0xe05a, 0x04);
231 		regmap_write(lt8713sx->regmap,  0xe05a, 0x00);
232 		regmap_write(lt8713sx->regmap,  0xe05b, flashaddr >> 16);
233 		regmap_write(lt8713sx->regmap,  0xe05c, flashaddr >> 8);
234 		regmap_write(lt8713sx->regmap,  0xe05d, flashaddr);
235 		regmap_write(lt8713sx->regmap,  0xe05a, 0x01);
236 		regmap_write(lt8713sx->regmap,  0xe05a, 0x00);
237 		msleep(100);
238 		i = 0;
239 		while (1) {
240 			flash_status = lt8713sx_read_flash_status(lt8713sx);
241 			if ((flash_status & 0x01) == 0)
242 				break;
243 
244 			if (i > 50)
245 				break;
246 
247 			i++;
248 			msleep(50);
249 		}
250 	}
251 	dev_dbg(lt8713sx->dev, "erase flash done.\n");
252 }
253 
254 static void lt8713sx_load_main_fw_to_sram(struct lt8713sx *lt8713sx)
255 {
256 	regmap_write(lt8713sx->regmap, 0xe068, 0x00);
257 	regmap_write(lt8713sx->regmap, 0xe069, 0x00);
258 	regmap_write(lt8713sx->regmap, 0xe06a, 0x00);
259 	regmap_write(lt8713sx->regmap, 0xe065, 0x00);
260 	regmap_write(lt8713sx->regmap, 0xe066, 0xff);
261 	regmap_write(lt8713sx->regmap, 0xe067, 0xff);
262 	regmap_write(lt8713sx->regmap, 0xe06b, 0x00);
263 	regmap_write(lt8713sx->regmap, 0xe06c, 0x00);
264 	regmap_write(lt8713sx->regmap, 0xe060, 0x01);
265 	msleep(200);
266 	regmap_write(lt8713sx->regmap, 0xe060, 0x00);
267 }
268 
269 static void lt8713sx_load_bank_fw_to_sram(struct lt8713sx *lt8713sx, u64 addr)
270 {
271 	regmap_write(lt8713sx->regmap, 0xe068, ((addr & 0xff0000) >> 16));
272 	regmap_write(lt8713sx->regmap, 0xe069, ((addr & 0x00ff00) >> 8));
273 	regmap_write(lt8713sx->regmap, 0xe06a, (addr & 0x0000ff));
274 	regmap_write(lt8713sx->regmap, 0xe065, 0x00);
275 	regmap_write(lt8713sx->regmap, 0xe066, 0x30);
276 	regmap_write(lt8713sx->regmap, 0xe067, 0x00);
277 	regmap_write(lt8713sx->regmap, 0xe06b, 0x00);
278 	regmap_write(lt8713sx->regmap, 0xe06c, 0x00);
279 	regmap_write(lt8713sx->regmap, 0xe060, 0x01);
280 	msleep(50);
281 	regmap_write(lt8713sx->regmap, 0xe060, 0x00);
282 }
283 
284 static int lt8713sx_write_data(struct lt8713sx *lt8713sx, const u8 *data, u64 filesize)
285 {
286 	int page = 0, num = 0, i = 0, val;
287 
288 	page = (filesize % LT8713SX_PAGE_SIZE) ?
289 			((filesize / LT8713SX_PAGE_SIZE) + 1) : (filesize / LT8713SX_PAGE_SIZE);
290 
291 	dev_dbg(lt8713sx->dev,
292 		"Writing to Sram=%u pages, total size = %llu bytes\n", page, filesize);
293 
294 	for (num = 0; num < page; num++) {
295 		dev_dbg(lt8713sx->dev, "page[%d]\n", num);
296 		lt8713sx_i2c_to_sram(lt8713sx);
297 
298 		for (i = 0; i < LT8713SX_PAGE_SIZE; i++) {
299 			if ((num * LT8713SX_PAGE_SIZE + i) < filesize)
300 				val = *(data + (num * LT8713SX_PAGE_SIZE + i));
301 			else
302 				val = 0xff;
303 			regmap_write(lt8713sx->regmap, 0xe059, val);
304 		}
305 
306 		lt8713sx_wren(lt8713sx);
307 		lt8713sx_sram_to_flash(lt8713sx);
308 	}
309 
310 	lt8713sx_wrdi(lt8713sx);
311 	lt8713sx_disable_sram_write(lt8713sx);
312 
313 	return 0;
314 }
315 
316 static void lt8713sx_main_upgrade_result(struct lt8713sx *lt8713sx)
317 {
318 	u32 main_crc_result;
319 
320 	regmap_read(lt8713sx->regmap, 0xe023, &main_crc_result);
321 
322 	dev_dbg(lt8713sx->dev, "Main CRC HW: 0x%02X\n", main_crc_result);
323 	dev_dbg(lt8713sx->dev, "Main CRC FW: 0x%02X\n", lt8713sx->main_crc_value);
324 
325 	if (main_crc_result == lt8713sx->main_crc_value)
326 		dev_info(lt8713sx->dev, "Main Firmware Upgrade Success.\n");
327 	else
328 		dev_err(lt8713sx->dev, "Main Firmware Upgrade Failed.\n");
329 }
330 
331 static void lt8713sx_bank_upgrade_result(struct lt8713sx *lt8713sx, u8 banknum)
332 {
333 	u32 bank_crc_result;
334 
335 	regmap_read(lt8713sx->regmap, 0xe023, &bank_crc_result);
336 
337 	dev_dbg(lt8713sx->dev, "Bank %d CRC Result: 0x%02X\n", banknum, bank_crc_result);
338 
339 	if (bank_crc_result == lt8713sx->bank_crc_value[banknum])
340 		dev_info(lt8713sx->dev, "Bank %d Firmware Upgrade Success.\n", banknum);
341 	else
342 		dev_err(lt8713sx->dev, "Bank %d Firmware Upgrade Failed.\n", banknum);
343 }
344 
345 static void lt8713sx_bank_result_check(struct lt8713sx *lt8713sx)
346 {
347 	int i;
348 	u64 addr = 0x010000;
349 
350 	for (i = 0; i < lt8713sx->bank_num; i++) {
351 		lt8713sx_load_bank_fw_to_sram(lt8713sx, addr);
352 		lt8713sx_bank_upgrade_result(lt8713sx, i);
353 		addr += 0x3000;
354 	}
355 }
356 
357 static int lt8713sx_firmware_upgrade(struct lt8713sx *lt8713sx)
358 {
359 	int ret;
360 
361 	lt8713sx_config_parameters(lt8713sx);
362 
363 	lt8713sx_block_erase(lt8713sx);
364 
365 	if (lt8713sx->fw->size < SZ_64K) {
366 		ret = lt8713sx_write_data(lt8713sx, lt8713sx->fw_buffer, SZ_64K);
367 		if (ret < 0) {
368 			dev_err(lt8713sx->dev, "Failed to write firmware data: %d\n", ret);
369 			return ret;
370 		}
371 	} else {
372 		ret = lt8713sx_write_data(lt8713sx, lt8713sx->fw_buffer, lt8713sx->fw->size);
373 		if (ret < 0) {
374 			dev_err(lt8713sx->dev, "Failed to write firmware data: %d\n", ret);
375 			return ret;
376 		}
377 	}
378 	dev_dbg(lt8713sx->dev, "Write Data done.\n");
379 
380 	return 0;
381 }
382 
383 static int lt8713sx_firmware_update(struct lt8713sx *lt8713sx)
384 {
385 	int ret = 0;
386 
387 	guard(mutex)(&lt8713sx->ocm_lock);
388 	lt8713sx_i2c_enable(lt8713sx);
389 
390 	ret = lt8713sx_prepare_firmware_data(lt8713sx);
391 	if (ret < 0) {
392 		dev_err(lt8713sx->dev, "Failed to prepare firmware data: %d\n", ret);
393 		goto error;
394 	}
395 
396 	ret = lt8713sx_firmware_upgrade(lt8713sx);
397 	if (ret < 0) {
398 		dev_err(lt8713sx->dev, "Upgrade failure.\n");
399 		goto error;
400 	}
401 
402 	/* Validate CRC */
403 	lt8713sx_load_main_fw_to_sram(lt8713sx);
404 	lt8713sx_main_upgrade_result(lt8713sx);
405 	lt8713sx_wrdi(lt8713sx);
406 	lt8713sx_fifo_reset(lt8713sx);
407 	lt8713sx_bank_result_check(lt8713sx);
408 	lt8713sx_wrdi(lt8713sx);
409 
410 error:
411 	lt8713sx_i2c_disable(lt8713sx);
412 	if (!ret)
413 		lt8713sx_reset(lt8713sx);
414 
415 	kvfree(lt8713sx->fw_buffer);
416 	lt8713sx->fw_buffer = NULL;
417 
418 	if (lt8713sx->fw) {
419 		release_firmware(lt8713sx->fw);
420 		lt8713sx->fw = NULL;
421 	}
422 
423 	return ret;
424 }
425 
426 static void lt8713sx_reset(struct lt8713sx *lt8713sx)
427 {
428 	dev_dbg(lt8713sx->dev, "reset bridge.\n");
429 	gpiod_set_value_cansleep(lt8713sx->reset_gpio, 1);
430 	msleep(20);
431 
432 	gpiod_set_value_cansleep(lt8713sx->reset_gpio, 0);
433 	msleep(20);
434 
435 	dev_dbg(lt8713sx->dev, "reset done.\n");
436 }
437 
438 static int lt8713sx_regulator_enable(struct lt8713sx *lt8713sx)
439 {
440 	int ret;
441 
442 	ret = devm_regulator_get_enable(lt8713sx->dev, "vdd");
443 	if (ret < 0)
444 		return dev_err_probe(lt8713sx->dev, ret, "failed to enable vdd regulator\n");
445 
446 	usleep_range(1000, 10000);
447 
448 	ret = devm_regulator_get_enable(lt8713sx->dev, "vcc");
449 	if (ret < 0)
450 		return dev_err_probe(lt8713sx->dev, ret, "failed to enable vcc regulator\n");
451 	return 0;
452 }
453 
454 static int lt8713sx_bridge_attach(struct drm_bridge *bridge,
455 				  struct drm_encoder *encoder,
456 				  enum drm_bridge_attach_flags flags)
457 {
458 	struct lt8713sx *lt8713sx = container_of(bridge, struct lt8713sx, bridge);
459 
460 	return drm_bridge_attach(encoder,
461 				lt8713sx->next_bridge,
462 				bridge, flags);
463 }
464 
465 static int lt8713sx_gpio_init(struct lt8713sx *lt8713sx)
466 {
467 	struct device *dev = lt8713sx->dev;
468 
469 	lt8713sx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
470 	if (IS_ERR(lt8713sx->reset_gpio))
471 		return dev_err_probe(dev, PTR_ERR(lt8713sx->reset_gpio),
472 				     "failed to acquire reset gpio\n");
473 
474 	/* power enable gpio */
475 	lt8713sx->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH);
476 	if (IS_ERR(lt8713sx->enable_gpio))
477 		return dev_err_probe(dev, PTR_ERR(lt8713sx->enable_gpio),
478 				     "failed to acquire enable gpio\n");
479 	return 0;
480 }
481 
482 static ssize_t lt8713sx_firmware_store(struct device *dev,
483 				       struct device_attribute *attr,
484 				       const char *buf, size_t len)
485 {
486 	struct lt8713sx *lt8713sx = dev_get_drvdata(dev);
487 	int ret;
488 
489 	ret = lt8713sx_firmware_update(lt8713sx);
490 	if (ret < 0)
491 		return ret;
492 	return len;
493 }
494 
495 static DEVICE_ATTR_WO(lt8713sx_firmware);
496 
497 static struct attribute *lt8713sx_attrs[] = {
498 	&dev_attr_lt8713sx_firmware.attr,
499 	NULL,
500 };
501 
502 static const struct attribute_group lt8713sx_attr_group = {
503 	.attrs = lt8713sx_attrs,
504 };
505 
506 static const struct attribute_group *lt8713sx_attr_groups[] = {
507 	&lt8713sx_attr_group,
508 	NULL,
509 };
510 
511 static const struct drm_bridge_funcs lt8713sx_bridge_funcs = {
512 	.attach = lt8713sx_bridge_attach,
513 };
514 
515 static int lt8713sx_probe(struct i2c_client *client)
516 {
517 	struct lt8713sx *lt8713sx;
518 	struct device *dev = &client->dev;
519 	int ret;
520 
521 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
522 		return dev_err_probe(dev, -ENODEV, "device doesn't support I2C\n");
523 
524 	lt8713sx = devm_drm_bridge_alloc(dev, struct lt8713sx, bridge, &lt8713sx_bridge_funcs);
525 	if (IS_ERR(lt8713sx))
526 		return PTR_ERR(lt8713sx);
527 
528 	lt8713sx->dev = dev;
529 	lt8713sx->client = client;
530 	i2c_set_clientdata(client, lt8713sx);
531 
532 	ret = devm_mutex_init(lt8713sx->dev, &lt8713sx->ocm_lock);
533 	if (ret)
534 		return ret;
535 
536 	lt8713sx->regmap = devm_regmap_init_i2c(client, &lt8713sx_regmap_config);
537 	if (IS_ERR(lt8713sx->regmap))
538 		return dev_err_probe(dev, PTR_ERR(lt8713sx->regmap), "regmap i2c init failed\n");
539 
540 	ret = drm_of_find_panel_or_bridge(lt8713sx->dev->of_node, 1, -1, NULL,
541 					  &lt8713sx->next_bridge);
542 	if (ret < 0)
543 		return ret;
544 
545 	ret = lt8713sx_gpio_init(lt8713sx);
546 	if (ret < 0)
547 		return ret;
548 
549 	ret = lt8713sx_regulator_enable(lt8713sx);
550 	if (ret)
551 		return ret;
552 
553 	lt8713sx_reset(lt8713sx);
554 
555 	lt8713sx->bridge.funcs = &lt8713sx_bridge_funcs;
556 	lt8713sx->bridge.of_node = dev->of_node;
557 	lt8713sx->bridge.type = DRM_MODE_CONNECTOR_DisplayPort;
558 	drm_bridge_add(&lt8713sx->bridge);
559 
560 	crc8_populate_msb(lt8713sx_crc_table, 0x31);
561 
562 	return 0;
563 }
564 
565 static void lt8713sx_remove(struct i2c_client *client)
566 {
567 	struct lt8713sx *lt8713sx = i2c_get_clientdata(client);
568 
569 	drm_bridge_remove(&lt8713sx->bridge);
570 }
571 
572 static struct i2c_device_id lt8713sx_id[] = {
573 	{ "lontium,lt8713sx", 0 },
574 	{ /* sentinel */ }
575 };
576 
577 static const struct of_device_id lt8713sx_match_table[] = {
578 	{ .compatible = "lontium,lt8713sx" },
579 	{ /* sentinel */ }
580 };
581 MODULE_DEVICE_TABLE(of, lt8713sx_match_table);
582 
583 static struct i2c_driver lt8713sx_driver = {
584 	.driver = {
585 		.name = "lt8713sx",
586 		.of_match_table = lt8713sx_match_table,
587 		.dev_groups = lt8713sx_attr_groups,
588 	},
589 	.probe = lt8713sx_probe,
590 	.remove = lt8713sx_remove,
591 	.id_table = lt8713sx_id,
592 };
593 
594 module_i2c_driver(lt8713sx_driver);
595 MODULE_LICENSE("GPL");
596 MODULE_DESCRIPTION("lt8713sx drm bridge driver");
597 MODULE_AUTHOR("Vishnu Saini <vishnu.saini@oss.qualcomm.com>");
598 MODULE_FIRMWARE(FW_FILE);
599