1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * Copyright (c) 2016 MediaTek Inc.
4 */
5
6 #include <linux/delay.h>
7 #include <linux/err.h>
8 #include <linux/gpio/consumer.h>
9 #include <linux/i2c.h>
10 #include <linux/module.h>
11 #include <linux/of_graph.h>
12 #include <linux/regmap.h>
13 #include <linux/regulator/consumer.h>
14
15 #include <drm/drm_bridge.h>
16 #include <drm/drm_dp_helper.h>
17 #include <drm/drm_mipi_dsi.h>
18 #include <drm/drm_of.h>
19 #include <drm/drm_panel.h>
20 #include <drm/drm_print.h>
21
22 #define PAGE0_AUXCH_CFG3 0x76
23 #define AUXCH_CFG3_RESET 0xff
24 #define PAGE0_SWAUX_ADDR_7_0 0x7d
25 #define PAGE0_SWAUX_ADDR_15_8 0x7e
26 #define PAGE0_SWAUX_ADDR_23_16 0x7f
27 #define SWAUX_ADDR_MASK GENMASK(19, 0)
28 #define PAGE0_SWAUX_LENGTH 0x80
29 #define SWAUX_LENGTH_MASK GENMASK(3, 0)
30 #define SWAUX_NO_PAYLOAD BIT(7)
31 #define PAGE0_SWAUX_WDATA 0x81
32 #define PAGE0_SWAUX_RDATA 0x82
33 #define PAGE0_SWAUX_CTRL 0x83
34 #define SWAUX_SEND BIT(0)
35 #define PAGE0_SWAUX_STATUS 0x84
36 #define SWAUX_M_MASK GENMASK(4, 0)
37 #define SWAUX_STATUS_MASK GENMASK(7, 5)
38 #define SWAUX_STATUS_NACK (0x1 << 5)
39 #define SWAUX_STATUS_DEFER (0x2 << 5)
40 #define SWAUX_STATUS_ACKM (0x3 << 5)
41 #define SWAUX_STATUS_INVALID (0x4 << 5)
42 #define SWAUX_STATUS_I2C_NACK (0x5 << 5)
43 #define SWAUX_STATUS_I2C_DEFER (0x6 << 5)
44 #define SWAUX_STATUS_TIMEOUT (0x7 << 5)
45
46 #define PAGE2_GPIO_H 0xa7
47 #define PS_GPIO9 BIT(1)
48 #define PAGE2_I2C_BYPASS 0xea
49 #define I2C_BYPASS_EN 0xd0
50 #define PAGE2_MCS_EN 0xf3
51 #define MCS_EN BIT(0)
52
53 #define PAGE3_SET_ADD 0xfe
54 #define VDO_CTL_ADD 0x13
55 #define VDO_DIS 0x18
56 #define VDO_EN 0x1c
57
58 #define NUM_MIPI_LANES 4
59
60 #define COMMON_PS8640_REGMAP_CONFIG \
61 .reg_bits = 8, \
62 .val_bits = 8, \
63 .cache_type = REGCACHE_NONE
64
65 /*
66 * PS8640 uses multiple addresses:
67 * page[0]: for DP control
68 * page[1]: for VIDEO Bridge
69 * page[2]: for control top
70 * page[3]: for DSI Link Control1
71 * page[4]: for MIPI Phy
72 * page[5]: for VPLL
73 * page[6]: for DSI Link Control2
74 * page[7]: for SPI ROM mapping
75 */
76 enum page_addr_offset {
77 PAGE0_DP_CNTL = 0,
78 PAGE1_VDO_BDG,
79 PAGE2_TOP_CNTL,
80 PAGE3_DSI_CNTL1,
81 PAGE4_MIPI_PHY,
82 PAGE5_VPLL,
83 PAGE6_DSI_CNTL2,
84 PAGE7_SPI_CNTL,
85 MAX_DEVS
86 };
87
88 enum ps8640_vdo_control {
89 DISABLE = VDO_DIS,
90 ENABLE = VDO_EN,
91 };
92
93 struct ps8640 {
94 struct drm_bridge bridge;
95 struct drm_bridge *panel_bridge;
96 struct drm_dp_aux aux;
97 struct mipi_dsi_device *dsi;
98 struct i2c_client *page[MAX_DEVS];
99 struct regmap *regmap[MAX_DEVS];
100 struct regulator_bulk_data supplies[2];
101 struct gpio_desc *gpio_reset;
102 struct gpio_desc *gpio_powerdown;
103 bool powered;
104 };
105
106 static const struct regmap_config ps8640_regmap_config[] = {
107 [PAGE0_DP_CNTL] = {
108 COMMON_PS8640_REGMAP_CONFIG,
109 .max_register = 0xbf,
110 },
111 [PAGE1_VDO_BDG] = {
112 COMMON_PS8640_REGMAP_CONFIG,
113 .max_register = 0xff,
114 },
115 [PAGE2_TOP_CNTL] = {
116 COMMON_PS8640_REGMAP_CONFIG,
117 .max_register = 0xff,
118 },
119 [PAGE3_DSI_CNTL1] = {
120 COMMON_PS8640_REGMAP_CONFIG,
121 .max_register = 0xff,
122 },
123 [PAGE4_MIPI_PHY] = {
124 COMMON_PS8640_REGMAP_CONFIG,
125 .max_register = 0xff,
126 },
127 [PAGE5_VPLL] = {
128 COMMON_PS8640_REGMAP_CONFIG,
129 .max_register = 0x7f,
130 },
131 [PAGE6_DSI_CNTL2] = {
132 COMMON_PS8640_REGMAP_CONFIG,
133 .max_register = 0xff,
134 },
135 [PAGE7_SPI_CNTL] = {
136 COMMON_PS8640_REGMAP_CONFIG,
137 .max_register = 0xff,
138 },
139 };
140
bridge_to_ps8640(struct drm_bridge * e)141 static inline struct ps8640 *bridge_to_ps8640(struct drm_bridge *e)
142 {
143 return container_of(e, struct ps8640, bridge);
144 }
145
aux_to_ps8640(struct drm_dp_aux * aux)146 static inline struct ps8640 *aux_to_ps8640(struct drm_dp_aux *aux)
147 {
148 return container_of(aux, struct ps8640, aux);
149 }
150
ps8640_aux_transfer(struct drm_dp_aux * aux,struct drm_dp_aux_msg * msg)151 static ssize_t ps8640_aux_transfer(struct drm_dp_aux *aux,
152 struct drm_dp_aux_msg *msg)
153 {
154 struct ps8640 *ps_bridge = aux_to_ps8640(aux);
155 struct regmap *map = ps_bridge->regmap[PAGE0_DP_CNTL];
156 struct device *dev = &ps_bridge->page[PAGE0_DP_CNTL]->dev;
157 unsigned int len = msg->size;
158 unsigned int data;
159 unsigned int base;
160 int ret;
161 u8 request = msg->request &
162 ~(DP_AUX_I2C_MOT | DP_AUX_I2C_WRITE_STATUS_UPDATE);
163 u8 *buf = msg->buffer;
164 u8 addr_len[PAGE0_SWAUX_LENGTH + 1 - PAGE0_SWAUX_ADDR_7_0];
165 u8 i;
166 bool is_native_aux = false;
167
168 if (len > DP_AUX_MAX_PAYLOAD_BYTES)
169 return -EINVAL;
170
171 if (msg->address & ~SWAUX_ADDR_MASK)
172 return -EINVAL;
173
174 switch (request) {
175 case DP_AUX_NATIVE_WRITE:
176 case DP_AUX_NATIVE_READ:
177 is_native_aux = true;
178 fallthrough;
179 case DP_AUX_I2C_WRITE:
180 case DP_AUX_I2C_READ:
181 break;
182 default:
183 return -EINVAL;
184 }
185
186 ret = regmap_write(map, PAGE0_AUXCH_CFG3, AUXCH_CFG3_RESET);
187 if (ret) {
188 DRM_DEV_ERROR(dev, "failed to write PAGE0_AUXCH_CFG3: %d\n",
189 ret);
190 return ret;
191 }
192
193 /* Assume it's good */
194 msg->reply = 0;
195
196 base = PAGE0_SWAUX_ADDR_7_0;
197 addr_len[PAGE0_SWAUX_ADDR_7_0 - base] = msg->address;
198 addr_len[PAGE0_SWAUX_ADDR_15_8 - base] = msg->address >> 8;
199 addr_len[PAGE0_SWAUX_ADDR_23_16 - base] = (msg->address >> 16) |
200 (msg->request << 4);
201 addr_len[PAGE0_SWAUX_LENGTH - base] = (len == 0) ? SWAUX_NO_PAYLOAD :
202 ((len - 1) & SWAUX_LENGTH_MASK);
203
204 regmap_bulk_write(map, PAGE0_SWAUX_ADDR_7_0, addr_len,
205 ARRAY_SIZE(addr_len));
206
207 if (len && (request == DP_AUX_NATIVE_WRITE ||
208 request == DP_AUX_I2C_WRITE)) {
209 /* Write to the internal FIFO buffer */
210 for (i = 0; i < len; i++) {
211 ret = regmap_write(map, PAGE0_SWAUX_WDATA, buf[i]);
212 if (ret) {
213 DRM_DEV_ERROR(dev,
214 "failed to write WDATA: %d\n",
215 ret);
216 return ret;
217 }
218 }
219 }
220
221 regmap_write(map, PAGE0_SWAUX_CTRL, SWAUX_SEND);
222
223 /* Zero delay loop because i2c transactions are slow already */
224 regmap_read_poll_timeout(map, PAGE0_SWAUX_CTRL, data,
225 !(data & SWAUX_SEND), 0, 50 * 1000);
226
227 regmap_read(map, PAGE0_SWAUX_STATUS, &data);
228 if (ret) {
229 DRM_DEV_ERROR(dev, "failed to read PAGE0_SWAUX_STATUS: %d\n",
230 ret);
231 return ret;
232 }
233
234 switch (data & SWAUX_STATUS_MASK) {
235 /* Ignore the DEFER cases as they are already handled in hardware */
236 case SWAUX_STATUS_NACK:
237 case SWAUX_STATUS_I2C_NACK:
238 /*
239 * The programming guide is not clear about whether a I2C NACK
240 * would trigger SWAUX_STATUS_NACK or SWAUX_STATUS_I2C_NACK. So
241 * we handle both cases together.
242 */
243 if (is_native_aux)
244 msg->reply |= DP_AUX_NATIVE_REPLY_NACK;
245 else
246 msg->reply |= DP_AUX_I2C_REPLY_NACK;
247
248 fallthrough;
249 case SWAUX_STATUS_ACKM:
250 len = data & SWAUX_M_MASK;
251 break;
252 case SWAUX_STATUS_INVALID:
253 return -EOPNOTSUPP;
254 case SWAUX_STATUS_TIMEOUT:
255 return -ETIMEDOUT;
256 }
257
258 if (len && (request == DP_AUX_NATIVE_READ ||
259 request == DP_AUX_I2C_READ)) {
260 /* Read from the internal FIFO buffer */
261 for (i = 0; i < len; i++) {
262 ret = regmap_read(map, PAGE0_SWAUX_RDATA, &data);
263 if (ret) {
264 DRM_DEV_ERROR(dev,
265 "failed to read RDATA: %d\n",
266 ret);
267 return ret;
268 }
269
270 buf[i] = data;
271 }
272 }
273
274 return len;
275 }
276
ps8640_bridge_vdo_control(struct ps8640 * ps_bridge,const enum ps8640_vdo_control ctrl)277 static int ps8640_bridge_vdo_control(struct ps8640 *ps_bridge,
278 const enum ps8640_vdo_control ctrl)
279 {
280 struct regmap *map = ps_bridge->regmap[PAGE3_DSI_CNTL1];
281 u8 vdo_ctrl_buf[] = { VDO_CTL_ADD, ctrl };
282 int ret;
283
284 ret = regmap_bulk_write(map, PAGE3_SET_ADD,
285 vdo_ctrl_buf, sizeof(vdo_ctrl_buf));
286
287 if (ret < 0) {
288 DRM_ERROR("failed to %sable VDO: %d\n",
289 ctrl == ENABLE ? "en" : "dis", ret);
290 return ret;
291 }
292
293 return 0;
294 }
295
ps8640_bridge_poweron(struct ps8640 * ps_bridge)296 static void ps8640_bridge_poweron(struct ps8640 *ps_bridge)
297 {
298 struct regmap *map = ps_bridge->regmap[PAGE2_TOP_CNTL];
299 int ret, status;
300
301 if (ps_bridge->powered)
302 return;
303
304 ret = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies),
305 ps_bridge->supplies);
306 if (ret < 0) {
307 DRM_ERROR("cannot enable regulators %d\n", ret);
308 return;
309 }
310
311 gpiod_set_value(ps_bridge->gpio_powerdown, 0);
312 gpiod_set_value(ps_bridge->gpio_reset, 1);
313 usleep_range(2000, 2500);
314 gpiod_set_value(ps_bridge->gpio_reset, 0);
315
316 /*
317 * Wait for the ps8640 embedded MCU to be ready
318 * First wait 200ms and then check the MCU ready flag every 20ms
319 */
320 msleep(200);
321
322 ret = regmap_read_poll_timeout(map, PAGE2_GPIO_H, status,
323 status & PS_GPIO9, 20 * 1000, 200 * 1000);
324
325 if (ret < 0) {
326 DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", ret);
327 goto err_regulators_disable;
328 }
329
330 msleep(50);
331
332 /*
333 * The Manufacturer Command Set (MCS) is a device dependent interface
334 * intended for factory programming of the display module default
335 * parameters. Once the display module is configured, the MCS shall be
336 * disabled by the manufacturer. Once disabled, all MCS commands are
337 * ignored by the display interface.
338 */
339
340 ret = regmap_update_bits(map, PAGE2_MCS_EN, MCS_EN, 0);
341 if (ret < 0) {
342 DRM_ERROR("failed write PAGE2_MCS_EN: %d\n", ret);
343 goto err_regulators_disable;
344 }
345
346 /* Switch access edp panel's edid through i2c */
347 ret = regmap_write(map, PAGE2_I2C_BYPASS, I2C_BYPASS_EN);
348 if (ret < 0) {
349 DRM_ERROR("failed write PAGE2_I2C_BYPASS: %d\n", ret);
350 goto err_regulators_disable;
351 }
352
353 ps_bridge->powered = true;
354
355 return;
356
357 err_regulators_disable:
358 regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
359 ps_bridge->supplies);
360 }
361
ps8640_bridge_poweroff(struct ps8640 * ps_bridge)362 static void ps8640_bridge_poweroff(struct ps8640 *ps_bridge)
363 {
364 int ret;
365
366 if (!ps_bridge->powered)
367 return;
368
369 gpiod_set_value(ps_bridge->gpio_reset, 1);
370 gpiod_set_value(ps_bridge->gpio_powerdown, 1);
371 ret = regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies),
372 ps_bridge->supplies);
373 if (ret < 0)
374 DRM_ERROR("cannot disable regulators %d\n", ret);
375
376 ps_bridge->powered = false;
377 }
378
ps8640_pre_enable(struct drm_bridge * bridge)379 static void ps8640_pre_enable(struct drm_bridge *bridge)
380 {
381 struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
382 int ret;
383
384 ps8640_bridge_poweron(ps_bridge);
385
386 ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE);
387 if (ret < 0)
388 ps8640_bridge_poweroff(ps_bridge);
389 }
390
ps8640_post_disable(struct drm_bridge * bridge)391 static void ps8640_post_disable(struct drm_bridge *bridge)
392 {
393 struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
394
395 ps8640_bridge_vdo_control(ps_bridge, DISABLE);
396 ps8640_bridge_poweroff(ps_bridge);
397 }
398
ps8640_bridge_attach(struct drm_bridge * bridge,enum drm_bridge_attach_flags flags)399 static int ps8640_bridge_attach(struct drm_bridge *bridge,
400 enum drm_bridge_attach_flags flags)
401 {
402 struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
403 struct device *dev = &ps_bridge->page[0]->dev;
404 struct device_node *in_ep, *dsi_node;
405 struct mipi_dsi_device *dsi;
406 struct mipi_dsi_host *host;
407 int ret;
408 const struct mipi_dsi_device_info info = { .type = "ps8640",
409 .channel = 0,
410 .node = NULL,
411 };
412
413 if (!(flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR))
414 return -EINVAL;
415
416 /* port@0 is ps8640 dsi input port */
417 in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1);
418 if (!in_ep)
419 return -ENODEV;
420
421 dsi_node = of_graph_get_remote_port_parent(in_ep);
422 of_node_put(in_ep);
423 if (!dsi_node)
424 return -ENODEV;
425
426 host = of_find_mipi_dsi_host_by_node(dsi_node);
427 of_node_put(dsi_node);
428 if (!host)
429 return -ENODEV;
430
431 dsi = mipi_dsi_device_register_full(host, &info);
432 if (IS_ERR(dsi)) {
433 dev_err(dev, "failed to create dsi device\n");
434 ret = PTR_ERR(dsi);
435 return ret;
436 }
437
438 ps_bridge->dsi = dsi;
439
440 dsi->host = host;
441 dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
442 MIPI_DSI_MODE_VIDEO_SYNC_PULSE;
443 dsi->format = MIPI_DSI_FMT_RGB888;
444 dsi->lanes = NUM_MIPI_LANES;
445 ret = mipi_dsi_attach(dsi);
446 if (ret) {
447 dev_err(dev, "failed to attach dsi device: %d\n", ret);
448 goto err_dsi_attach;
449 }
450
451 ret = drm_dp_aux_register(&ps_bridge->aux);
452 if (ret) {
453 dev_err(dev, "failed to register DP AUX channel: %d\n", ret);
454 goto err_aux_register;
455 }
456
457 /* Attach the panel-bridge to the dsi bridge */
458 return drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge,
459 &ps_bridge->bridge, flags);
460
461 err_aux_register:
462 mipi_dsi_detach(dsi);
463 err_dsi_attach:
464 mipi_dsi_device_unregister(dsi);
465 return ret;
466 }
467
ps8640_bridge_detach(struct drm_bridge * bridge)468 static void ps8640_bridge_detach(struct drm_bridge *bridge)
469 {
470 drm_dp_aux_unregister(&bridge_to_ps8640(bridge)->aux);
471 }
472
ps8640_bridge_get_edid(struct drm_bridge * bridge,struct drm_connector * connector)473 static struct edid *ps8640_bridge_get_edid(struct drm_bridge *bridge,
474 struct drm_connector *connector)
475 {
476 struct ps8640 *ps_bridge = bridge_to_ps8640(bridge);
477 bool poweroff = !ps_bridge->powered;
478 struct edid *edid;
479
480 /*
481 * When we end calling get_edid() triggered by an ioctl, i.e
482 *
483 * drm_mode_getconnector (ioctl)
484 * -> drm_helper_probe_single_connector_modes
485 * -> drm_bridge_connector_get_modes
486 * -> ps8640_bridge_get_edid
487 *
488 * We need to make sure that what we need is enabled before reading
489 * EDID, for this chip, we need to do a full poweron, otherwise it will
490 * fail.
491 */
492 drm_bridge_chain_pre_enable(bridge);
493
494 edid = drm_get_edid(connector,
495 ps_bridge->page[PAGE0_DP_CNTL]->adapter);
496
497 /*
498 * If we call the get_edid() function without having enabled the chip
499 * before, return the chip to its original power state.
500 */
501 if (poweroff)
502 drm_bridge_chain_post_disable(bridge);
503
504 return edid;
505 }
506
507 static const struct drm_bridge_funcs ps8640_bridge_funcs = {
508 .attach = ps8640_bridge_attach,
509 .detach = ps8640_bridge_detach,
510 .get_edid = ps8640_bridge_get_edid,
511 .post_disable = ps8640_post_disable,
512 .pre_enable = ps8640_pre_enable,
513 };
514
ps8640_probe(struct i2c_client * client)515 static int ps8640_probe(struct i2c_client *client)
516 {
517 struct device *dev = &client->dev;
518 struct device_node *np = dev->of_node;
519 struct ps8640 *ps_bridge;
520 struct drm_panel *panel;
521 int ret;
522 u32 i;
523
524 ps_bridge = devm_kzalloc(dev, sizeof(*ps_bridge), GFP_KERNEL);
525 if (!ps_bridge)
526 return -ENOMEM;
527
528 /* port@1 is ps8640 output port */
529 ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL);
530 if (ret < 0)
531 return ret;
532 if (!panel)
533 return -ENODEV;
534
535 ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel);
536 if (IS_ERR(ps_bridge->panel_bridge))
537 return PTR_ERR(ps_bridge->panel_bridge);
538
539 ps_bridge->supplies[0].supply = "vdd33";
540 ps_bridge->supplies[1].supply = "vdd12";
541 ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies),
542 ps_bridge->supplies);
543 if (ret)
544 return ret;
545
546 ps_bridge->gpio_powerdown = devm_gpiod_get(&client->dev, "powerdown",
547 GPIOD_OUT_HIGH);
548 if (IS_ERR(ps_bridge->gpio_powerdown))
549 return PTR_ERR(ps_bridge->gpio_powerdown);
550
551 /*
552 * Assert the reset to avoid the bridge being initialized prematurely
553 */
554 ps_bridge->gpio_reset = devm_gpiod_get(&client->dev, "reset",
555 GPIOD_OUT_HIGH);
556 if (IS_ERR(ps_bridge->gpio_reset))
557 return PTR_ERR(ps_bridge->gpio_reset);
558
559 ps_bridge->bridge.funcs = &ps8640_bridge_funcs;
560 ps_bridge->bridge.of_node = dev->of_node;
561 ps_bridge->bridge.ops = DRM_BRIDGE_OP_EDID;
562 ps_bridge->bridge.type = DRM_MODE_CONNECTOR_eDP;
563
564 ps_bridge->page[PAGE0_DP_CNTL] = client;
565
566 ps_bridge->regmap[PAGE0_DP_CNTL] = devm_regmap_init_i2c(client, ps8640_regmap_config);
567 if (IS_ERR(ps_bridge->regmap[PAGE0_DP_CNTL]))
568 return PTR_ERR(ps_bridge->regmap[PAGE0_DP_CNTL]);
569
570 for (i = 1; i < ARRAY_SIZE(ps_bridge->page); i++) {
571 ps_bridge->page[i] = devm_i2c_new_dummy_device(&client->dev,
572 client->adapter,
573 client->addr + i);
574 if (IS_ERR(ps_bridge->page[i]))
575 return PTR_ERR(ps_bridge->page[i]);
576
577 ps_bridge->regmap[i] = devm_regmap_init_i2c(ps_bridge->page[i],
578 ps8640_regmap_config + i);
579 if (IS_ERR(ps_bridge->regmap[i]))
580 return PTR_ERR(ps_bridge->regmap[i]);
581 }
582
583 i2c_set_clientdata(client, ps_bridge);
584
585 ps_bridge->aux.name = "parade-ps8640-aux";
586 ps_bridge->aux.dev = dev;
587 ps_bridge->aux.transfer = ps8640_aux_transfer;
588 drm_dp_aux_init(&ps_bridge->aux);
589
590 drm_bridge_add(&ps_bridge->bridge);
591
592 return 0;
593 }
594
ps8640_remove(struct i2c_client * client)595 static int ps8640_remove(struct i2c_client *client)
596 {
597 struct ps8640 *ps_bridge = i2c_get_clientdata(client);
598
599 drm_bridge_remove(&ps_bridge->bridge);
600
601 return 0;
602 }
603
604 static const struct of_device_id ps8640_match[] = {
605 { .compatible = "parade,ps8640" },
606 { }
607 };
608 MODULE_DEVICE_TABLE(of, ps8640_match);
609
610 static struct i2c_driver ps8640_driver = {
611 .probe_new = ps8640_probe,
612 .remove = ps8640_remove,
613 .driver = {
614 .name = "ps8640",
615 .of_match_table = ps8640_match,
616 },
617 };
618 module_i2c_driver(ps8640_driver);
619
620 MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>");
621 MODULE_AUTHOR("CK Hu <ck.hu@mediatek.com>");
622 MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>");
623 MODULE_DESCRIPTION("PARADE ps8640 DSI-eDP converter driver");
624 MODULE_LICENSE("GPL v2");
625