1*bc1aee7fSJitao Shi // SPDX-License-Identifier: GPL-2.0-only 2*bc1aee7fSJitao Shi /* 3*bc1aee7fSJitao Shi * Copyright (c) 2016 MediaTek Inc. 4*bc1aee7fSJitao Shi */ 5*bc1aee7fSJitao Shi 6*bc1aee7fSJitao Shi #include <linux/delay.h> 7*bc1aee7fSJitao Shi #include <linux/err.h> 8*bc1aee7fSJitao Shi #include <linux/gpio/consumer.h> 9*bc1aee7fSJitao Shi #include <linux/i2c.h> 10*bc1aee7fSJitao Shi #include <linux/module.h> 11*bc1aee7fSJitao Shi #include <linux/of_graph.h> 12*bc1aee7fSJitao Shi #include <linux/regulator/consumer.h> 13*bc1aee7fSJitao Shi 14*bc1aee7fSJitao Shi #include <drm/drm_bridge.h> 15*bc1aee7fSJitao Shi #include <drm/drm_mipi_dsi.h> 16*bc1aee7fSJitao Shi #include <drm/drm_of.h> 17*bc1aee7fSJitao Shi #include <drm/drm_panel.h> 18*bc1aee7fSJitao Shi #include <drm/drm_print.h> 19*bc1aee7fSJitao Shi 20*bc1aee7fSJitao Shi #define PAGE2_GPIO_H 0xa7 21*bc1aee7fSJitao Shi #define PS_GPIO9 BIT(1) 22*bc1aee7fSJitao Shi #define PAGE2_I2C_BYPASS 0xea 23*bc1aee7fSJitao Shi #define I2C_BYPASS_EN 0xd0 24*bc1aee7fSJitao Shi #define PAGE2_MCS_EN 0xf3 25*bc1aee7fSJitao Shi #define MCS_EN BIT(0) 26*bc1aee7fSJitao Shi #define PAGE3_SET_ADD 0xfe 27*bc1aee7fSJitao Shi #define VDO_CTL_ADD 0x13 28*bc1aee7fSJitao Shi #define VDO_DIS 0x18 29*bc1aee7fSJitao Shi #define VDO_EN 0x1c 30*bc1aee7fSJitao Shi #define DP_NUM_LANES 4 31*bc1aee7fSJitao Shi 32*bc1aee7fSJitao Shi /* 33*bc1aee7fSJitao Shi * PS8640 uses multiple addresses: 34*bc1aee7fSJitao Shi * page[0]: for DP control 35*bc1aee7fSJitao Shi * page[1]: for VIDEO Bridge 36*bc1aee7fSJitao Shi * page[2]: for control top 37*bc1aee7fSJitao Shi * page[3]: for DSI Link Control1 38*bc1aee7fSJitao Shi * page[4]: for MIPI Phy 39*bc1aee7fSJitao Shi * page[5]: for VPLL 40*bc1aee7fSJitao Shi * page[6]: for DSI Link Control2 41*bc1aee7fSJitao Shi * page[7]: for SPI ROM mapping 42*bc1aee7fSJitao Shi */ 43*bc1aee7fSJitao Shi enum page_addr_offset { 44*bc1aee7fSJitao Shi PAGE0_DP_CNTL = 0, 45*bc1aee7fSJitao Shi PAGE1_VDO_BDG, 46*bc1aee7fSJitao Shi PAGE2_TOP_CNTL, 47*bc1aee7fSJitao Shi PAGE3_DSI_CNTL1, 48*bc1aee7fSJitao Shi PAGE4_MIPI_PHY, 49*bc1aee7fSJitao Shi PAGE5_VPLL, 50*bc1aee7fSJitao Shi PAGE6_DSI_CNTL2, 51*bc1aee7fSJitao Shi PAGE7_SPI_CNTL, 52*bc1aee7fSJitao Shi MAX_DEVS 53*bc1aee7fSJitao Shi }; 54*bc1aee7fSJitao Shi 55*bc1aee7fSJitao Shi enum ps8640_vdo_control { 56*bc1aee7fSJitao Shi DISABLE = VDO_DIS, 57*bc1aee7fSJitao Shi ENABLE = VDO_EN, 58*bc1aee7fSJitao Shi }; 59*bc1aee7fSJitao Shi 60*bc1aee7fSJitao Shi struct ps8640 { 61*bc1aee7fSJitao Shi struct drm_bridge bridge; 62*bc1aee7fSJitao Shi struct drm_bridge *panel_bridge; 63*bc1aee7fSJitao Shi struct mipi_dsi_device *dsi; 64*bc1aee7fSJitao Shi struct i2c_client *page[MAX_DEVS]; 65*bc1aee7fSJitao Shi struct regulator_bulk_data supplies[2]; 66*bc1aee7fSJitao Shi struct gpio_desc *gpio_reset; 67*bc1aee7fSJitao Shi struct gpio_desc *gpio_powerdown; 68*bc1aee7fSJitao Shi }; 69*bc1aee7fSJitao Shi 70*bc1aee7fSJitao Shi static inline struct ps8640 *bridge_to_ps8640(struct drm_bridge *e) 71*bc1aee7fSJitao Shi { 72*bc1aee7fSJitao Shi return container_of(e, struct ps8640, bridge); 73*bc1aee7fSJitao Shi } 74*bc1aee7fSJitao Shi 75*bc1aee7fSJitao Shi static int ps8640_bridge_vdo_control(struct ps8640 *ps_bridge, 76*bc1aee7fSJitao Shi const enum ps8640_vdo_control ctrl) 77*bc1aee7fSJitao Shi { 78*bc1aee7fSJitao Shi struct i2c_client *client = ps_bridge->page[PAGE3_DSI_CNTL1]; 79*bc1aee7fSJitao Shi u8 vdo_ctrl_buf[] = { VDO_CTL_ADD, ctrl }; 80*bc1aee7fSJitao Shi int ret; 81*bc1aee7fSJitao Shi 82*bc1aee7fSJitao Shi ret = i2c_smbus_write_i2c_block_data(client, PAGE3_SET_ADD, 83*bc1aee7fSJitao Shi sizeof(vdo_ctrl_buf), 84*bc1aee7fSJitao Shi vdo_ctrl_buf); 85*bc1aee7fSJitao Shi if (ret < 0) 86*bc1aee7fSJitao Shi return ret; 87*bc1aee7fSJitao Shi 88*bc1aee7fSJitao Shi return 0; 89*bc1aee7fSJitao Shi } 90*bc1aee7fSJitao Shi 91*bc1aee7fSJitao Shi static void ps8640_pre_enable(struct drm_bridge *bridge) 92*bc1aee7fSJitao Shi { 93*bc1aee7fSJitao Shi struct ps8640 *ps_bridge = bridge_to_ps8640(bridge); 94*bc1aee7fSJitao Shi struct i2c_client *client = ps_bridge->page[PAGE2_TOP_CNTL]; 95*bc1aee7fSJitao Shi unsigned long timeout; 96*bc1aee7fSJitao Shi int ret, status; 97*bc1aee7fSJitao Shi 98*bc1aee7fSJitao Shi ret = regulator_bulk_enable(ARRAY_SIZE(ps_bridge->supplies), 99*bc1aee7fSJitao Shi ps_bridge->supplies); 100*bc1aee7fSJitao Shi if (ret < 0) { 101*bc1aee7fSJitao Shi DRM_ERROR("cannot enable regulators %d\n", ret); 102*bc1aee7fSJitao Shi return; 103*bc1aee7fSJitao Shi } 104*bc1aee7fSJitao Shi 105*bc1aee7fSJitao Shi gpiod_set_value(ps_bridge->gpio_powerdown, 0); 106*bc1aee7fSJitao Shi gpiod_set_value(ps_bridge->gpio_reset, 1); 107*bc1aee7fSJitao Shi usleep_range(2000, 2500); 108*bc1aee7fSJitao Shi gpiod_set_value(ps_bridge->gpio_reset, 0); 109*bc1aee7fSJitao Shi 110*bc1aee7fSJitao Shi /* 111*bc1aee7fSJitao Shi * Wait for the ps8640 embedded MCU to be ready 112*bc1aee7fSJitao Shi * First wait 200ms and then check the MCU ready flag every 20ms 113*bc1aee7fSJitao Shi */ 114*bc1aee7fSJitao Shi msleep(200); 115*bc1aee7fSJitao Shi 116*bc1aee7fSJitao Shi timeout = jiffies + msecs_to_jiffies(200) + 1; 117*bc1aee7fSJitao Shi 118*bc1aee7fSJitao Shi while (time_is_after_jiffies(timeout)) { 119*bc1aee7fSJitao Shi status = i2c_smbus_read_byte_data(client, PAGE2_GPIO_H); 120*bc1aee7fSJitao Shi if (status < 0) { 121*bc1aee7fSJitao Shi DRM_ERROR("failed read PAGE2_GPIO_H: %d\n", status); 122*bc1aee7fSJitao Shi goto err_regulators_disable; 123*bc1aee7fSJitao Shi } 124*bc1aee7fSJitao Shi if ((status & PS_GPIO9) == PS_GPIO9) 125*bc1aee7fSJitao Shi break; 126*bc1aee7fSJitao Shi 127*bc1aee7fSJitao Shi msleep(20); 128*bc1aee7fSJitao Shi } 129*bc1aee7fSJitao Shi 130*bc1aee7fSJitao Shi msleep(50); 131*bc1aee7fSJitao Shi 132*bc1aee7fSJitao Shi /* 133*bc1aee7fSJitao Shi * The Manufacturer Command Set (MCS) is a device dependent interface 134*bc1aee7fSJitao Shi * intended for factory programming of the display module default 135*bc1aee7fSJitao Shi * parameters. Once the display module is configured, the MCS shall be 136*bc1aee7fSJitao Shi * disabled by the manufacturer. Once disabled, all MCS commands are 137*bc1aee7fSJitao Shi * ignored by the display interface. 138*bc1aee7fSJitao Shi */ 139*bc1aee7fSJitao Shi status = i2c_smbus_read_byte_data(client, PAGE2_MCS_EN); 140*bc1aee7fSJitao Shi if (status < 0) { 141*bc1aee7fSJitao Shi DRM_ERROR("failed read PAGE2_MCS_EN: %d\n", status); 142*bc1aee7fSJitao Shi goto err_regulators_disable; 143*bc1aee7fSJitao Shi } 144*bc1aee7fSJitao Shi 145*bc1aee7fSJitao Shi ret = i2c_smbus_write_byte_data(client, PAGE2_MCS_EN, 146*bc1aee7fSJitao Shi status & ~MCS_EN); 147*bc1aee7fSJitao Shi if (ret < 0) { 148*bc1aee7fSJitao Shi DRM_ERROR("failed write PAGE2_MCS_EN: %d\n", ret); 149*bc1aee7fSJitao Shi goto err_regulators_disable; 150*bc1aee7fSJitao Shi } 151*bc1aee7fSJitao Shi 152*bc1aee7fSJitao Shi ret = ps8640_bridge_vdo_control(ps_bridge, ENABLE); 153*bc1aee7fSJitao Shi if (ret) { 154*bc1aee7fSJitao Shi DRM_ERROR("failed to enable VDO: %d\n", ret); 155*bc1aee7fSJitao Shi goto err_regulators_disable; 156*bc1aee7fSJitao Shi } 157*bc1aee7fSJitao Shi 158*bc1aee7fSJitao Shi /* Switch access edp panel's edid through i2c */ 159*bc1aee7fSJitao Shi ret = i2c_smbus_write_byte_data(client, PAGE2_I2C_BYPASS, 160*bc1aee7fSJitao Shi I2C_BYPASS_EN); 161*bc1aee7fSJitao Shi if (ret < 0) { 162*bc1aee7fSJitao Shi DRM_ERROR("failed write PAGE2_I2C_BYPASS: %d\n", ret); 163*bc1aee7fSJitao Shi goto err_regulators_disable; 164*bc1aee7fSJitao Shi } 165*bc1aee7fSJitao Shi 166*bc1aee7fSJitao Shi return; 167*bc1aee7fSJitao Shi 168*bc1aee7fSJitao Shi err_regulators_disable: 169*bc1aee7fSJitao Shi regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies), 170*bc1aee7fSJitao Shi ps_bridge->supplies); 171*bc1aee7fSJitao Shi } 172*bc1aee7fSJitao Shi 173*bc1aee7fSJitao Shi static void ps8640_post_disable(struct drm_bridge *bridge) 174*bc1aee7fSJitao Shi { 175*bc1aee7fSJitao Shi struct ps8640 *ps_bridge = bridge_to_ps8640(bridge); 176*bc1aee7fSJitao Shi int ret; 177*bc1aee7fSJitao Shi 178*bc1aee7fSJitao Shi ret = ps8640_bridge_vdo_control(ps_bridge, DISABLE); 179*bc1aee7fSJitao Shi if (ret < 0) 180*bc1aee7fSJitao Shi DRM_ERROR("failed to disable VDO: %d\n", ret); 181*bc1aee7fSJitao Shi 182*bc1aee7fSJitao Shi gpiod_set_value(ps_bridge->gpio_reset, 1); 183*bc1aee7fSJitao Shi gpiod_set_value(ps_bridge->gpio_powerdown, 1); 184*bc1aee7fSJitao Shi ret = regulator_bulk_disable(ARRAY_SIZE(ps_bridge->supplies), 185*bc1aee7fSJitao Shi ps_bridge->supplies); 186*bc1aee7fSJitao Shi if (ret < 0) 187*bc1aee7fSJitao Shi DRM_ERROR("cannot disable regulators %d\n", ret); 188*bc1aee7fSJitao Shi } 189*bc1aee7fSJitao Shi 190*bc1aee7fSJitao Shi static int ps8640_bridge_attach(struct drm_bridge *bridge) 191*bc1aee7fSJitao Shi { 192*bc1aee7fSJitao Shi struct ps8640 *ps_bridge = bridge_to_ps8640(bridge); 193*bc1aee7fSJitao Shi struct device *dev = &ps_bridge->page[0]->dev; 194*bc1aee7fSJitao Shi struct device_node *in_ep, *dsi_node; 195*bc1aee7fSJitao Shi struct mipi_dsi_device *dsi; 196*bc1aee7fSJitao Shi struct mipi_dsi_host *host; 197*bc1aee7fSJitao Shi int ret; 198*bc1aee7fSJitao Shi const struct mipi_dsi_device_info info = { .type = "ps8640", 199*bc1aee7fSJitao Shi .channel = 0, 200*bc1aee7fSJitao Shi .node = NULL, 201*bc1aee7fSJitao Shi }; 202*bc1aee7fSJitao Shi /* port@0 is ps8640 dsi input port */ 203*bc1aee7fSJitao Shi in_ep = of_graph_get_endpoint_by_regs(dev->of_node, 0, -1); 204*bc1aee7fSJitao Shi if (!in_ep) 205*bc1aee7fSJitao Shi return -ENODEV; 206*bc1aee7fSJitao Shi 207*bc1aee7fSJitao Shi dsi_node = of_graph_get_remote_port_parent(in_ep); 208*bc1aee7fSJitao Shi of_node_put(in_ep); 209*bc1aee7fSJitao Shi if (!dsi_node) 210*bc1aee7fSJitao Shi return -ENODEV; 211*bc1aee7fSJitao Shi 212*bc1aee7fSJitao Shi host = of_find_mipi_dsi_host_by_node(dsi_node); 213*bc1aee7fSJitao Shi of_node_put(dsi_node); 214*bc1aee7fSJitao Shi if (!host) 215*bc1aee7fSJitao Shi return -ENODEV; 216*bc1aee7fSJitao Shi 217*bc1aee7fSJitao Shi dsi = mipi_dsi_device_register_full(host, &info); 218*bc1aee7fSJitao Shi if (IS_ERR(dsi)) { 219*bc1aee7fSJitao Shi dev_err(dev, "failed to create dsi device\n"); 220*bc1aee7fSJitao Shi ret = PTR_ERR(dsi); 221*bc1aee7fSJitao Shi return ret; 222*bc1aee7fSJitao Shi } 223*bc1aee7fSJitao Shi 224*bc1aee7fSJitao Shi ps_bridge->dsi = dsi; 225*bc1aee7fSJitao Shi 226*bc1aee7fSJitao Shi dsi->host = host; 227*bc1aee7fSJitao Shi dsi->mode_flags = MIPI_DSI_MODE_VIDEO | 228*bc1aee7fSJitao Shi MIPI_DSI_MODE_VIDEO_SYNC_PULSE; 229*bc1aee7fSJitao Shi dsi->format = MIPI_DSI_FMT_RGB888; 230*bc1aee7fSJitao Shi dsi->lanes = DP_NUM_LANES; 231*bc1aee7fSJitao Shi ret = mipi_dsi_attach(dsi); 232*bc1aee7fSJitao Shi if (ret) 233*bc1aee7fSJitao Shi goto err_dsi_attach; 234*bc1aee7fSJitao Shi 235*bc1aee7fSJitao Shi /* Attach the panel-bridge to the dsi bridge */ 236*bc1aee7fSJitao Shi return drm_bridge_attach(bridge->encoder, ps_bridge->panel_bridge, 237*bc1aee7fSJitao Shi &ps_bridge->bridge); 238*bc1aee7fSJitao Shi 239*bc1aee7fSJitao Shi err_dsi_attach: 240*bc1aee7fSJitao Shi mipi_dsi_device_unregister(dsi); 241*bc1aee7fSJitao Shi return ret; 242*bc1aee7fSJitao Shi } 243*bc1aee7fSJitao Shi 244*bc1aee7fSJitao Shi static const struct drm_bridge_funcs ps8640_bridge_funcs = { 245*bc1aee7fSJitao Shi .attach = ps8640_bridge_attach, 246*bc1aee7fSJitao Shi .post_disable = ps8640_post_disable, 247*bc1aee7fSJitao Shi .pre_enable = ps8640_pre_enable, 248*bc1aee7fSJitao Shi }; 249*bc1aee7fSJitao Shi 250*bc1aee7fSJitao Shi static int ps8640_probe(struct i2c_client *client) 251*bc1aee7fSJitao Shi { 252*bc1aee7fSJitao Shi struct device *dev = &client->dev; 253*bc1aee7fSJitao Shi struct device_node *np = dev->of_node; 254*bc1aee7fSJitao Shi struct ps8640 *ps_bridge; 255*bc1aee7fSJitao Shi struct drm_panel *panel; 256*bc1aee7fSJitao Shi int ret; 257*bc1aee7fSJitao Shi u32 i; 258*bc1aee7fSJitao Shi 259*bc1aee7fSJitao Shi ps_bridge = devm_kzalloc(dev, sizeof(*ps_bridge), GFP_KERNEL); 260*bc1aee7fSJitao Shi if (!ps_bridge) 261*bc1aee7fSJitao Shi return -ENOMEM; 262*bc1aee7fSJitao Shi 263*bc1aee7fSJitao Shi /* port@1 is ps8640 output port */ 264*bc1aee7fSJitao Shi ret = drm_of_find_panel_or_bridge(np, 1, 0, &panel, NULL); 265*bc1aee7fSJitao Shi if (ret < 0) 266*bc1aee7fSJitao Shi return ret; 267*bc1aee7fSJitao Shi if (!panel) 268*bc1aee7fSJitao Shi return -ENODEV; 269*bc1aee7fSJitao Shi 270*bc1aee7fSJitao Shi panel->connector_type = DRM_MODE_CONNECTOR_eDP; 271*bc1aee7fSJitao Shi 272*bc1aee7fSJitao Shi ps_bridge->panel_bridge = devm_drm_panel_bridge_add(dev, panel); 273*bc1aee7fSJitao Shi if (IS_ERR(ps_bridge->panel_bridge)) 274*bc1aee7fSJitao Shi return PTR_ERR(ps_bridge->panel_bridge); 275*bc1aee7fSJitao Shi 276*bc1aee7fSJitao Shi ps_bridge->supplies[0].supply = "vdd33"; 277*bc1aee7fSJitao Shi ps_bridge->supplies[1].supply = "vdd12"; 278*bc1aee7fSJitao Shi ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ps_bridge->supplies), 279*bc1aee7fSJitao Shi ps_bridge->supplies); 280*bc1aee7fSJitao Shi if (ret) 281*bc1aee7fSJitao Shi return ret; 282*bc1aee7fSJitao Shi 283*bc1aee7fSJitao Shi ps_bridge->gpio_powerdown = devm_gpiod_get(&client->dev, "powerdown", 284*bc1aee7fSJitao Shi GPIOD_OUT_HIGH); 285*bc1aee7fSJitao Shi if (IS_ERR(ps_bridge->gpio_powerdown)) 286*bc1aee7fSJitao Shi return PTR_ERR(ps_bridge->gpio_powerdown); 287*bc1aee7fSJitao Shi 288*bc1aee7fSJitao Shi /* 289*bc1aee7fSJitao Shi * Assert the reset to avoid the bridge being initialized prematurely 290*bc1aee7fSJitao Shi */ 291*bc1aee7fSJitao Shi ps_bridge->gpio_reset = devm_gpiod_get(&client->dev, "reset", 292*bc1aee7fSJitao Shi GPIOD_OUT_HIGH); 293*bc1aee7fSJitao Shi if (IS_ERR(ps_bridge->gpio_reset)) 294*bc1aee7fSJitao Shi return PTR_ERR(ps_bridge->gpio_reset); 295*bc1aee7fSJitao Shi 296*bc1aee7fSJitao Shi ps_bridge->bridge.funcs = &ps8640_bridge_funcs; 297*bc1aee7fSJitao Shi ps_bridge->bridge.of_node = dev->of_node; 298*bc1aee7fSJitao Shi 299*bc1aee7fSJitao Shi ps_bridge->page[PAGE0_DP_CNTL] = client; 300*bc1aee7fSJitao Shi 301*bc1aee7fSJitao Shi for (i = 1; i < ARRAY_SIZE(ps_bridge->page); i++) { 302*bc1aee7fSJitao Shi ps_bridge->page[i] = devm_i2c_new_dummy_device(&client->dev, 303*bc1aee7fSJitao Shi client->adapter, 304*bc1aee7fSJitao Shi client->addr + i); 305*bc1aee7fSJitao Shi if (IS_ERR(ps_bridge->page[i])) { 306*bc1aee7fSJitao Shi dev_err(dev, "failed i2c dummy device, address %02x\n", 307*bc1aee7fSJitao Shi client->addr + i); 308*bc1aee7fSJitao Shi return PTR_ERR(ps_bridge->page[i]); 309*bc1aee7fSJitao Shi } 310*bc1aee7fSJitao Shi } 311*bc1aee7fSJitao Shi 312*bc1aee7fSJitao Shi i2c_set_clientdata(client, ps_bridge); 313*bc1aee7fSJitao Shi 314*bc1aee7fSJitao Shi drm_bridge_add(&ps_bridge->bridge); 315*bc1aee7fSJitao Shi 316*bc1aee7fSJitao Shi return 0; 317*bc1aee7fSJitao Shi } 318*bc1aee7fSJitao Shi 319*bc1aee7fSJitao Shi static int ps8640_remove(struct i2c_client *client) 320*bc1aee7fSJitao Shi { 321*bc1aee7fSJitao Shi struct ps8640 *ps_bridge = i2c_get_clientdata(client); 322*bc1aee7fSJitao Shi 323*bc1aee7fSJitao Shi drm_bridge_remove(&ps_bridge->bridge); 324*bc1aee7fSJitao Shi 325*bc1aee7fSJitao Shi return 0; 326*bc1aee7fSJitao Shi } 327*bc1aee7fSJitao Shi 328*bc1aee7fSJitao Shi static const struct of_device_id ps8640_match[] = { 329*bc1aee7fSJitao Shi { .compatible = "parade,ps8640" }, 330*bc1aee7fSJitao Shi { } 331*bc1aee7fSJitao Shi }; 332*bc1aee7fSJitao Shi MODULE_DEVICE_TABLE(of, ps8640_match); 333*bc1aee7fSJitao Shi 334*bc1aee7fSJitao Shi static struct i2c_driver ps8640_driver = { 335*bc1aee7fSJitao Shi .probe_new = ps8640_probe, 336*bc1aee7fSJitao Shi .remove = ps8640_remove, 337*bc1aee7fSJitao Shi .driver = { 338*bc1aee7fSJitao Shi .name = "ps8640", 339*bc1aee7fSJitao Shi .of_match_table = ps8640_match, 340*bc1aee7fSJitao Shi }, 341*bc1aee7fSJitao Shi }; 342*bc1aee7fSJitao Shi module_i2c_driver(ps8640_driver); 343*bc1aee7fSJitao Shi 344*bc1aee7fSJitao Shi MODULE_AUTHOR("Jitao Shi <jitao.shi@mediatek.com>"); 345*bc1aee7fSJitao Shi MODULE_AUTHOR("CK Hu <ck.hu@mediatek.com>"); 346*bc1aee7fSJitao Shi MODULE_AUTHOR("Enric Balletbo i Serra <enric.balletbo@collabora.com>"); 347*bc1aee7fSJitao Shi MODULE_DESCRIPTION("PARADE ps8640 DSI-eDP converter driver"); 348*bc1aee7fSJitao Shi MODULE_LICENSE("GPL v2"); 349