1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2019 Laurent Pinchart <laurent.pinchart@ideasonboard.com> 4 */ 5 6 #include <linux/gpio/consumer.h> 7 #include <linux/i2c.h> 8 #include <linux/interrupt.h> 9 #include <linux/media-bus-format.h> 10 #include <linux/module.h> 11 #include <linux/mutex.h> 12 #include <linux/of.h> 13 #include <linux/platform_device.h> 14 #include <linux/regulator/consumer.h> 15 #include <linux/workqueue.h> 16 17 #include <drm/drm_atomic_helper.h> 18 #include <drm/drm_bridge.h> 19 #include <drm/drm_edid.h> 20 21 struct display_connector { 22 struct drm_bridge bridge; 23 24 struct gpio_desc *hpd_gpio; 25 int hpd_irq; 26 27 struct regulator *supply; 28 struct gpio_desc *ddc_en; 29 30 struct work_struct hpd_work; 31 }; 32 33 static inline struct display_connector * 34 to_display_connector(struct drm_bridge *bridge) 35 { 36 return container_of(bridge, struct display_connector, bridge); 37 } 38 39 static int display_connector_attach(struct drm_bridge *bridge, 40 struct drm_encoder *encoder, 41 enum drm_bridge_attach_flags flags) 42 { 43 return flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR ? 0 : -EINVAL; 44 } 45 46 static void display_connector_destroy(struct drm_bridge *bridge) 47 { 48 struct display_connector *conn = to_display_connector(bridge); 49 50 i2c_put_adapter(conn->bridge.ddc); 51 } 52 53 static enum drm_connector_status display_connector_detect(struct drm_bridge *bridge) 54 { 55 struct display_connector *conn = to_display_connector(bridge); 56 57 if (conn->hpd_gpio) { 58 if (gpiod_get_value_cansleep(conn->hpd_gpio)) 59 return connector_status_connected; 60 else 61 return connector_status_disconnected; 62 } 63 64 if (conn->bridge.ddc && drm_probe_ddc(conn->bridge.ddc)) 65 return connector_status_connected; 66 67 switch (conn->bridge.type) { 68 case DRM_MODE_CONNECTOR_DVIA: 69 case DRM_MODE_CONNECTOR_DVID: 70 case DRM_MODE_CONNECTOR_DVII: 71 case DRM_MODE_CONNECTOR_HDMIA: 72 case DRM_MODE_CONNECTOR_HDMIB: 73 /* 74 * For DVI and HDMI connectors a DDC probe failure indicates 75 * that no cable is connected. 76 */ 77 return connector_status_disconnected; 78 79 case DRM_MODE_CONNECTOR_Composite: 80 case DRM_MODE_CONNECTOR_SVIDEO: 81 case DRM_MODE_CONNECTOR_VGA: 82 default: 83 /* 84 * Composite and S-Video connectors have no other detection 85 * mean than the HPD GPIO. For VGA connectors, even if we have 86 * an I2C bus, we can't assume that the cable is disconnected 87 * if drm_probe_ddc fails, as some cables don't wire the DDC 88 * pins. 89 */ 90 return connector_status_unknown; 91 } 92 } 93 94 static enum drm_connector_status 95 display_connector_bridge_detect(struct drm_bridge *bridge, struct drm_connector *connector) 96 { 97 return display_connector_detect(bridge); 98 } 99 100 static void display_connector_hpd_enable(struct drm_bridge *bridge) 101 { 102 struct display_connector *conn = to_display_connector(bridge); 103 104 enable_irq(conn->hpd_irq); 105 106 if (conn->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) 107 schedule_work(&conn->hpd_work); 108 } 109 110 static void display_connector_hpd_disable(struct drm_bridge *bridge) 111 { 112 struct display_connector *conn = to_display_connector(bridge); 113 114 if (conn->bridge.type == DRM_MODE_CONNECTOR_DisplayPort) 115 cancel_work_sync(&conn->hpd_work); 116 117 disable_irq(conn->hpd_irq); 118 } 119 120 static void display_connector_hpd_work(struct work_struct *work) 121 { 122 struct display_connector *conn = container_of(work, struct display_connector, hpd_work); 123 struct drm_bridge *bridge = &conn->bridge; 124 125 drm_bridge_hpd_notify(bridge, display_connector_detect(bridge)); 126 } 127 128 static const struct drm_edid *display_connector_edid_read(struct drm_bridge *bridge, 129 struct drm_connector *connector) 130 { 131 struct display_connector *conn = to_display_connector(bridge); 132 133 return drm_edid_read_ddc(connector, conn->bridge.ddc); 134 } 135 136 /* 137 * Since this bridge is tied to the connector, it acts like a passthrough, 138 * so concerning the output bus formats, either pass the bus formats from the 139 * previous bridge or return fallback data like done in the bridge function: 140 * drm_atomic_bridge_chain_select_bus_fmts(). 141 * This supports negotiation if the bridge chain has all bits in place. 142 */ 143 static u32 *display_connector_get_output_bus_fmts(struct drm_bridge *bridge, 144 struct drm_bridge_state *bridge_state, 145 struct drm_crtc_state *crtc_state, 146 struct drm_connector_state *conn_state, 147 unsigned int *num_output_fmts) 148 { 149 struct drm_bridge *prev_bridge __free(drm_bridge_put) = drm_bridge_get_prev_bridge(bridge); 150 struct drm_bridge_state *prev_bridge_state; 151 152 if (!prev_bridge || !prev_bridge->funcs->atomic_get_output_bus_fmts) { 153 struct drm_connector *conn = conn_state->connector; 154 u32 *out_bus_fmts; 155 156 *num_output_fmts = 1; 157 out_bus_fmts = kmalloc_obj(*out_bus_fmts); 158 if (!out_bus_fmts) 159 return NULL; 160 161 if (conn->display_info.num_bus_formats && 162 conn->display_info.bus_formats) 163 out_bus_fmts[0] = conn->display_info.bus_formats[0]; 164 else 165 out_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; 166 167 return out_bus_fmts; 168 } 169 170 prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, 171 prev_bridge); 172 173 return prev_bridge->funcs->atomic_get_output_bus_fmts(prev_bridge, prev_bridge_state, 174 crtc_state, conn_state, 175 num_output_fmts); 176 } 177 178 /* 179 * Since this bridge is tied to the connector, it acts like a passthrough, 180 * so concerning the input bus formats, either pass the bus formats from the 181 * previous bridge or MEDIA_BUS_FMT_FIXED (like select_bus_fmt_recursive()) 182 * when atomic_get_input_bus_fmts is not supported. 183 * This supports negotiation if the bridge chain has all bits in place. 184 */ 185 static u32 *display_connector_get_input_bus_fmts(struct drm_bridge *bridge, 186 struct drm_bridge_state *bridge_state, 187 struct drm_crtc_state *crtc_state, 188 struct drm_connector_state *conn_state, 189 u32 output_fmt, 190 unsigned int *num_input_fmts) 191 { 192 struct drm_bridge *prev_bridge __free(drm_bridge_put) = drm_bridge_get_prev_bridge(bridge); 193 struct drm_bridge_state *prev_bridge_state; 194 195 if (!prev_bridge || !prev_bridge->funcs->atomic_get_input_bus_fmts) { 196 u32 *in_bus_fmts; 197 198 *num_input_fmts = 1; 199 in_bus_fmts = kmalloc_obj(*in_bus_fmts); 200 if (!in_bus_fmts) 201 return NULL; 202 203 in_bus_fmts[0] = MEDIA_BUS_FMT_FIXED; 204 205 return in_bus_fmts; 206 } 207 208 prev_bridge_state = drm_atomic_get_new_bridge_state(crtc_state->state, 209 prev_bridge); 210 211 return prev_bridge->funcs->atomic_get_input_bus_fmts(prev_bridge, prev_bridge_state, 212 crtc_state, conn_state, output_fmt, 213 num_input_fmts); 214 } 215 216 static const struct drm_bridge_funcs display_connector_bridge_funcs = { 217 .attach = display_connector_attach, 218 .destroy = display_connector_destroy, 219 .detect = display_connector_bridge_detect, 220 .hpd_enable = display_connector_hpd_enable, 221 .hpd_disable = display_connector_hpd_disable, 222 .edid_read = display_connector_edid_read, 223 .atomic_get_output_bus_fmts = display_connector_get_output_bus_fmts, 224 .atomic_get_input_bus_fmts = display_connector_get_input_bus_fmts, 225 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 226 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 227 .atomic_create_state = drm_atomic_helper_bridge_create_state, 228 }; 229 230 static irqreturn_t display_connector_hpd_irq(int irq, void *arg) 231 { 232 struct display_connector *conn = arg; 233 struct drm_bridge *bridge = &conn->bridge; 234 235 drm_bridge_hpd_notify(bridge, display_connector_detect(bridge)); 236 237 return IRQ_HANDLED; 238 } 239 240 static int display_connector_get_supply(struct platform_device *pdev, 241 struct display_connector *conn, 242 const char *name) 243 { 244 conn->supply = devm_regulator_get_optional(&pdev->dev, name); 245 246 if (conn->supply == ERR_PTR(-ENODEV)) 247 conn->supply = NULL; 248 249 return PTR_ERR_OR_ZERO(conn->supply); 250 } 251 252 static int display_connector_probe(struct platform_device *pdev) 253 { 254 struct display_connector *conn; 255 unsigned int type; 256 const char *label = NULL; 257 int ret; 258 259 conn = devm_drm_bridge_alloc(&pdev->dev, struct display_connector, bridge, 260 &display_connector_bridge_funcs); 261 if (IS_ERR(conn)) 262 return PTR_ERR(conn); 263 264 platform_set_drvdata(pdev, conn); 265 266 type = (uintptr_t)of_device_get_match_data(&pdev->dev); 267 268 /* Get the exact connector type. */ 269 switch (type) { 270 case DRM_MODE_CONNECTOR_DVII: { 271 bool analog, digital; 272 273 analog = of_property_read_bool(pdev->dev.of_node, "analog"); 274 digital = of_property_read_bool(pdev->dev.of_node, "digital"); 275 if (analog && !digital) { 276 conn->bridge.type = DRM_MODE_CONNECTOR_DVIA; 277 } else if (!analog && digital) { 278 conn->bridge.type = DRM_MODE_CONNECTOR_DVID; 279 } else if (analog && digital) { 280 conn->bridge.type = DRM_MODE_CONNECTOR_DVII; 281 } else { 282 dev_err(&pdev->dev, "DVI connector with no type\n"); 283 return -EINVAL; 284 } 285 break; 286 } 287 288 case DRM_MODE_CONNECTOR_HDMIA: { 289 const char *hdmi_type; 290 291 ret = of_property_read_string(pdev->dev.of_node, "type", 292 &hdmi_type); 293 if (ret < 0) { 294 dev_err(&pdev->dev, "HDMI connector with no type\n"); 295 return -EINVAL; 296 } 297 298 if (!strcmp(hdmi_type, "a") || !strcmp(hdmi_type, "c") || 299 !strcmp(hdmi_type, "d") || !strcmp(hdmi_type, "e")) { 300 conn->bridge.type = DRM_MODE_CONNECTOR_HDMIA; 301 } else if (!strcmp(hdmi_type, "b")) { 302 conn->bridge.type = DRM_MODE_CONNECTOR_HDMIB; 303 } else { 304 dev_err(&pdev->dev, 305 "Unsupported HDMI connector type '%s'\n", 306 hdmi_type); 307 return -EINVAL; 308 } 309 310 break; 311 } 312 313 default: 314 conn->bridge.type = type; 315 break; 316 } 317 318 /* All the supported connector types support interlaced modes. */ 319 conn->bridge.interlace_allowed = true; 320 321 if (type == DRM_MODE_CONNECTOR_HDMIA || 322 type == DRM_MODE_CONNECTOR_DisplayPort) 323 conn->bridge.ycbcr_420_allowed = true; 324 325 /* Get the optional connector label. */ 326 of_property_read_string(pdev->dev.of_node, "label", &label); 327 328 /* 329 * Get the HPD GPIO for DVI, HDMI and DP connectors. If the GPIO can provide 330 * edge interrupts, register an interrupt handler. 331 */ 332 if (type == DRM_MODE_CONNECTOR_DVII || 333 type == DRM_MODE_CONNECTOR_HDMIA || 334 type == DRM_MODE_CONNECTOR_DisplayPort) { 335 conn->hpd_gpio = devm_gpiod_get_optional(&pdev->dev, "hpd", 336 GPIOD_IN); 337 if (IS_ERR(conn->hpd_gpio)) 338 return dev_err_probe(&pdev->dev, PTR_ERR(conn->hpd_gpio), 339 "Unable to retrieve HPD GPIO\n"); 340 341 conn->hpd_irq = gpiod_to_irq(conn->hpd_gpio); 342 } else { 343 conn->hpd_irq = -EINVAL; 344 } 345 346 if (conn->hpd_irq >= 0) { 347 ret = devm_request_threaded_irq(&pdev->dev, conn->hpd_irq, 348 NULL, display_connector_hpd_irq, 349 IRQF_TRIGGER_RISING | 350 IRQF_TRIGGER_FALLING | 351 IRQF_NO_AUTOEN | 352 IRQF_ONESHOT, 353 "HPD", conn); 354 if (ret) { 355 dev_info(&pdev->dev, 356 "Failed to request HPD edge interrupt, falling back to polling\n"); 357 conn->hpd_irq = -EINVAL; 358 } 359 } 360 361 /* Retrieve the DDC I2C adapter for DVI, HDMI and VGA connectors. */ 362 if (type == DRM_MODE_CONNECTOR_DVII || 363 type == DRM_MODE_CONNECTOR_HDMIA || 364 type == DRM_MODE_CONNECTOR_VGA) { 365 struct device_node *phandle; 366 367 phandle = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0); 368 if (phandle) { 369 conn->bridge.ddc = of_get_i2c_adapter_by_node(phandle); 370 of_node_put(phandle); 371 if (!conn->bridge.ddc) 372 return -EPROBE_DEFER; 373 } else { 374 dev_dbg(&pdev->dev, 375 "No I2C bus specified, disabling EDID readout\n"); 376 } 377 } 378 379 /* Get the DP PWR for DP connector. */ 380 if (type == DRM_MODE_CONNECTOR_DisplayPort) { 381 int ret; 382 383 ret = display_connector_get_supply(pdev, conn, "dp-pwr"); 384 if (ret < 0) 385 return dev_err_probe(&pdev->dev, ret, "failed to get DP PWR regulator\n"); 386 } 387 388 /* enable DDC */ 389 if (type == DRM_MODE_CONNECTOR_HDMIA) { 390 int ret; 391 392 conn->ddc_en = devm_gpiod_get_optional(&pdev->dev, "ddc-en", 393 GPIOD_OUT_HIGH); 394 395 if (IS_ERR(conn->ddc_en)) { 396 dev_err(&pdev->dev, "Couldn't get ddc-en gpio\n"); 397 return PTR_ERR(conn->ddc_en); 398 } 399 400 ret = display_connector_get_supply(pdev, conn, "hdmi-pwr"); 401 if (ret < 0) 402 return dev_err_probe(&pdev->dev, ret, "failed to get HDMI +5V Power regulator\n"); 403 } 404 405 if (conn->supply) { 406 ret = regulator_enable(conn->supply); 407 if (ret) { 408 dev_err(&pdev->dev, "failed to enable PWR regulator: %d\n", ret); 409 return ret; 410 } 411 } 412 413 conn->bridge.of_node = pdev->dev.of_node; 414 415 if (conn->bridge.ddc) 416 conn->bridge.ops |= DRM_BRIDGE_OP_EDID 417 | DRM_BRIDGE_OP_DETECT; 418 /* Detecting the monitor requires reading DPCD */ 419 if (conn->hpd_gpio && type != DRM_MODE_CONNECTOR_DisplayPort) 420 conn->bridge.ops |= DRM_BRIDGE_OP_DETECT; 421 if (conn->hpd_irq >= 0) 422 conn->bridge.ops |= DRM_BRIDGE_OP_HPD; 423 if (conn->hpd_irq >= 0 && type == DRM_MODE_CONNECTOR_DisplayPort) 424 INIT_WORK(&conn->hpd_work, display_connector_hpd_work); 425 426 dev_dbg(&pdev->dev, 427 "Found %s display connector '%s' %s DDC bus and %s HPD GPIO (ops 0x%x)\n", 428 drm_get_connector_type_name(conn->bridge.type), 429 label ? label : "<unlabelled>", 430 conn->bridge.ddc ? "with" : "without", 431 conn->hpd_gpio ? "with" : "without", 432 conn->bridge.ops); 433 434 drm_bridge_add(&conn->bridge); 435 436 return 0; 437 } 438 439 static void display_connector_remove(struct platform_device *pdev) 440 { 441 struct display_connector *conn = platform_get_drvdata(pdev); 442 443 if (conn->ddc_en) 444 gpiod_set_value(conn->ddc_en, 0); 445 446 if (conn->supply) 447 regulator_disable(conn->supply); 448 449 drm_bridge_remove(&conn->bridge); 450 } 451 452 static const struct of_device_id display_connector_match[] = { 453 { 454 .compatible = "composite-video-connector", 455 .data = (void *)DRM_MODE_CONNECTOR_Composite, 456 }, { 457 .compatible = "dvi-connector", 458 .data = (void *)DRM_MODE_CONNECTOR_DVII, 459 }, { 460 .compatible = "hdmi-connector", 461 .data = (void *)DRM_MODE_CONNECTOR_HDMIA, 462 }, { 463 .compatible = "svideo-connector", 464 .data = (void *)DRM_MODE_CONNECTOR_SVIDEO, 465 }, { 466 .compatible = "vga-connector", 467 .data = (void *)DRM_MODE_CONNECTOR_VGA, 468 }, { 469 .compatible = "dp-connector", 470 .data = (void *)DRM_MODE_CONNECTOR_DisplayPort, 471 }, 472 {}, 473 }; 474 MODULE_DEVICE_TABLE(of, display_connector_match); 475 476 static struct platform_driver display_connector_driver = { 477 .probe = display_connector_probe, 478 .remove = display_connector_remove, 479 .driver = { 480 .name = "display-connector", 481 .of_match_table = display_connector_match, 482 }, 483 }; 484 module_platform_driver(display_connector_driver); 485 486 MODULE_AUTHOR("Laurent Pinchart <laurent.pinchart@ideasonboard.com>"); 487 MODULE_DESCRIPTION("Display connector driver"); 488 MODULE_LICENSE("GPL"); 489