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