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