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