10411374bSLaurent Pinchart // SPDX-License-Identifier: GPL-2.0-or-later 20411374bSLaurent Pinchart /* 30411374bSLaurent Pinchart * Copyright (C) 2015-2016 Free Electrons 40411374bSLaurent Pinchart * Copyright (C) 2015-2016 NextThing Co 50411374bSLaurent Pinchart * 60411374bSLaurent Pinchart * Maxime Ripard <maxime.ripard@free-electrons.com> 70411374bSLaurent Pinchart */ 80411374bSLaurent Pinchart 90411374bSLaurent Pinchart #include <linux/module.h> 100411374bSLaurent Pinchart #include <linux/of_device.h> 110411374bSLaurent Pinchart #include <linux/of_graph.h> 120411374bSLaurent Pinchart #include <linux/regulator/consumer.h> 130411374bSLaurent Pinchart 140411374bSLaurent Pinchart #include <drm/drm_atomic_helper.h> 150411374bSLaurent Pinchart #include <drm/drm_bridge.h> 160411374bSLaurent Pinchart #include <drm/drm_crtc.h> 170411374bSLaurent Pinchart #include <drm/drm_print.h> 180411374bSLaurent Pinchart #include <drm/drm_probe_helper.h> 190411374bSLaurent Pinchart 20272378ecSLaurent Pinchart struct simple_bridge_info { 21272378ecSLaurent Pinchart const struct drm_bridge_timings *timings; 22272378ecSLaurent Pinchart unsigned int connector_type; 23272378ecSLaurent Pinchart }; 24272378ecSLaurent Pinchart 250411374bSLaurent Pinchart struct simple_bridge { 260411374bSLaurent Pinchart struct drm_bridge bridge; 270411374bSLaurent Pinchart struct drm_connector connector; 280411374bSLaurent Pinchart 29272378ecSLaurent Pinchart const struct simple_bridge_info *info; 30272378ecSLaurent Pinchart 310411374bSLaurent Pinchart struct i2c_adapter *ddc; 320411374bSLaurent Pinchart struct regulator *vdd; 330411374bSLaurent Pinchart }; 340411374bSLaurent Pinchart 350411374bSLaurent Pinchart static inline struct simple_bridge * 360411374bSLaurent Pinchart drm_bridge_to_simple_bridge(struct drm_bridge *bridge) 370411374bSLaurent Pinchart { 380411374bSLaurent Pinchart return container_of(bridge, struct simple_bridge, bridge); 390411374bSLaurent Pinchart } 400411374bSLaurent Pinchart 410411374bSLaurent Pinchart static inline struct simple_bridge * 420411374bSLaurent Pinchart drm_connector_to_simple_bridge(struct drm_connector *connector) 430411374bSLaurent Pinchart { 440411374bSLaurent Pinchart return container_of(connector, struct simple_bridge, connector); 450411374bSLaurent Pinchart } 460411374bSLaurent Pinchart 470411374bSLaurent Pinchart static int simple_bridge_get_modes(struct drm_connector *connector) 480411374bSLaurent Pinchart { 490411374bSLaurent Pinchart struct simple_bridge *sbridge = drm_connector_to_simple_bridge(connector); 500411374bSLaurent Pinchart struct edid *edid; 510411374bSLaurent Pinchart int ret; 520411374bSLaurent Pinchart 530411374bSLaurent Pinchart if (!sbridge->ddc) 540411374bSLaurent Pinchart goto fallback; 550411374bSLaurent Pinchart 560411374bSLaurent Pinchart edid = drm_get_edid(connector, sbridge->ddc); 570411374bSLaurent Pinchart if (!edid) { 580411374bSLaurent Pinchart DRM_INFO("EDID readout failed, falling back to standard modes\n"); 590411374bSLaurent Pinchart goto fallback; 600411374bSLaurent Pinchart } 610411374bSLaurent Pinchart 620411374bSLaurent Pinchart drm_connector_update_edid_property(connector, edid); 630411374bSLaurent Pinchart ret = drm_add_edid_modes(connector, edid); 640411374bSLaurent Pinchart kfree(edid); 650411374bSLaurent Pinchart return ret; 660411374bSLaurent Pinchart 670411374bSLaurent Pinchart fallback: 680411374bSLaurent Pinchart /* 690411374bSLaurent Pinchart * In case we cannot retrieve the EDIDs (broken or missing i2c 700411374bSLaurent Pinchart * bus), fallback on the XGA standards 710411374bSLaurent Pinchart */ 720411374bSLaurent Pinchart ret = drm_add_modes_noedid(connector, 1920, 1200); 730411374bSLaurent Pinchart 740411374bSLaurent Pinchart /* And prefer a mode pretty much anyone can handle */ 750411374bSLaurent Pinchart drm_set_preferred_mode(connector, 1024, 768); 760411374bSLaurent Pinchart 770411374bSLaurent Pinchart return ret; 780411374bSLaurent Pinchart } 790411374bSLaurent Pinchart 800411374bSLaurent Pinchart static const struct drm_connector_helper_funcs simple_bridge_con_helper_funcs = { 810411374bSLaurent Pinchart .get_modes = simple_bridge_get_modes, 820411374bSLaurent Pinchart }; 830411374bSLaurent Pinchart 840411374bSLaurent Pinchart static enum drm_connector_status 850411374bSLaurent Pinchart simple_bridge_connector_detect(struct drm_connector *connector, bool force) 860411374bSLaurent Pinchart { 870411374bSLaurent Pinchart struct simple_bridge *sbridge = drm_connector_to_simple_bridge(connector); 880411374bSLaurent Pinchart 890411374bSLaurent Pinchart /* 900411374bSLaurent Pinchart * Even if we have an I2C bus, we can't assume that the cable 910411374bSLaurent Pinchart * is disconnected if drm_probe_ddc fails. Some cables don't 920411374bSLaurent Pinchart * wire the DDC pins, or the I2C bus might not be working at 930411374bSLaurent Pinchart * all. 940411374bSLaurent Pinchart */ 950411374bSLaurent Pinchart if (sbridge->ddc && drm_probe_ddc(sbridge->ddc)) 960411374bSLaurent Pinchart return connector_status_connected; 970411374bSLaurent Pinchart 980411374bSLaurent Pinchart return connector_status_unknown; 990411374bSLaurent Pinchart } 1000411374bSLaurent Pinchart 1010411374bSLaurent Pinchart static const struct drm_connector_funcs simple_bridge_con_funcs = { 1020411374bSLaurent Pinchart .detect = simple_bridge_connector_detect, 1030411374bSLaurent Pinchart .fill_modes = drm_helper_probe_single_connector_modes, 1040411374bSLaurent Pinchart .destroy = drm_connector_cleanup, 1050411374bSLaurent Pinchart .reset = drm_atomic_helper_connector_reset, 1060411374bSLaurent Pinchart .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, 1070411374bSLaurent Pinchart .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, 1080411374bSLaurent Pinchart }; 1090411374bSLaurent Pinchart 1100411374bSLaurent Pinchart static int simple_bridge_attach(struct drm_bridge *bridge, 1110411374bSLaurent Pinchart enum drm_bridge_attach_flags flags) 1120411374bSLaurent Pinchart { 1130411374bSLaurent Pinchart struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge); 1140411374bSLaurent Pinchart int ret; 1150411374bSLaurent Pinchart 1160411374bSLaurent Pinchart if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) { 1170411374bSLaurent Pinchart DRM_ERROR("Fix bridge driver to make connector optional!"); 1180411374bSLaurent Pinchart return -EINVAL; 1190411374bSLaurent Pinchart } 1200411374bSLaurent Pinchart 1210411374bSLaurent Pinchart if (!bridge->encoder) { 1220411374bSLaurent Pinchart DRM_ERROR("Missing encoder\n"); 1230411374bSLaurent Pinchart return -ENODEV; 1240411374bSLaurent Pinchart } 1250411374bSLaurent Pinchart 1260411374bSLaurent Pinchart drm_connector_helper_add(&sbridge->connector, 1270411374bSLaurent Pinchart &simple_bridge_con_helper_funcs); 1280411374bSLaurent Pinchart ret = drm_connector_init_with_ddc(bridge->dev, &sbridge->connector, 1290411374bSLaurent Pinchart &simple_bridge_con_funcs, 130272378ecSLaurent Pinchart sbridge->info->connector_type, 1310411374bSLaurent Pinchart sbridge->ddc); 1320411374bSLaurent Pinchart if (ret) { 1330411374bSLaurent Pinchart DRM_ERROR("Failed to initialize connector\n"); 1340411374bSLaurent Pinchart return ret; 1350411374bSLaurent Pinchart } 1360411374bSLaurent Pinchart 1370411374bSLaurent Pinchart drm_connector_attach_encoder(&sbridge->connector, 1380411374bSLaurent Pinchart bridge->encoder); 1390411374bSLaurent Pinchart 1400411374bSLaurent Pinchart return 0; 1410411374bSLaurent Pinchart } 1420411374bSLaurent Pinchart 1430411374bSLaurent Pinchart static void simple_bridge_enable(struct drm_bridge *bridge) 1440411374bSLaurent Pinchart { 1450411374bSLaurent Pinchart struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge); 1460411374bSLaurent Pinchart int ret = 0; 1470411374bSLaurent Pinchart 1480411374bSLaurent Pinchart if (sbridge->vdd) 1490411374bSLaurent Pinchart ret = regulator_enable(sbridge->vdd); 1500411374bSLaurent Pinchart 1510411374bSLaurent Pinchart if (ret) 1520411374bSLaurent Pinchart DRM_ERROR("Failed to enable vdd regulator: %d\n", ret); 1530411374bSLaurent Pinchart } 1540411374bSLaurent Pinchart 1550411374bSLaurent Pinchart static void simple_bridge_disable(struct drm_bridge *bridge) 1560411374bSLaurent Pinchart { 1570411374bSLaurent Pinchart struct simple_bridge *sbridge = drm_bridge_to_simple_bridge(bridge); 1580411374bSLaurent Pinchart 1590411374bSLaurent Pinchart if (sbridge->vdd) 1600411374bSLaurent Pinchart regulator_disable(sbridge->vdd); 1610411374bSLaurent Pinchart } 1620411374bSLaurent Pinchart 1630411374bSLaurent Pinchart static const struct drm_bridge_funcs simple_bridge_bridge_funcs = { 1640411374bSLaurent Pinchart .attach = simple_bridge_attach, 1650411374bSLaurent Pinchart .enable = simple_bridge_enable, 1660411374bSLaurent Pinchart .disable = simple_bridge_disable, 1670411374bSLaurent Pinchart }; 1680411374bSLaurent Pinchart 1690411374bSLaurent Pinchart static struct i2c_adapter *simple_bridge_retrieve_ddc(struct device *dev) 1700411374bSLaurent Pinchart { 1710411374bSLaurent Pinchart struct device_node *phandle, *remote; 1720411374bSLaurent Pinchart struct i2c_adapter *ddc; 1730411374bSLaurent Pinchart 1740411374bSLaurent Pinchart remote = of_graph_get_remote_node(dev->of_node, 1, -1); 1750411374bSLaurent Pinchart if (!remote) 1760411374bSLaurent Pinchart return ERR_PTR(-EINVAL); 1770411374bSLaurent Pinchart 1780411374bSLaurent Pinchart phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0); 1790411374bSLaurent Pinchart of_node_put(remote); 1800411374bSLaurent Pinchart if (!phandle) 1810411374bSLaurent Pinchart return ERR_PTR(-ENODEV); 1820411374bSLaurent Pinchart 1830411374bSLaurent Pinchart ddc = of_get_i2c_adapter_by_node(phandle); 1840411374bSLaurent Pinchart of_node_put(phandle); 1850411374bSLaurent Pinchart if (!ddc) 1860411374bSLaurent Pinchart return ERR_PTR(-EPROBE_DEFER); 1870411374bSLaurent Pinchart 1880411374bSLaurent Pinchart return ddc; 1890411374bSLaurent Pinchart } 1900411374bSLaurent Pinchart 1910411374bSLaurent Pinchart static int simple_bridge_probe(struct platform_device *pdev) 1920411374bSLaurent Pinchart { 1930411374bSLaurent Pinchart struct simple_bridge *sbridge; 1940411374bSLaurent Pinchart 1950411374bSLaurent Pinchart sbridge = devm_kzalloc(&pdev->dev, sizeof(*sbridge), GFP_KERNEL); 1960411374bSLaurent Pinchart if (!sbridge) 1970411374bSLaurent Pinchart return -ENOMEM; 1980411374bSLaurent Pinchart platform_set_drvdata(pdev, sbridge); 1990411374bSLaurent Pinchart 200272378ecSLaurent Pinchart sbridge->info = of_device_get_match_data(&pdev->dev); 201272378ecSLaurent Pinchart 2020411374bSLaurent Pinchart sbridge->vdd = devm_regulator_get_optional(&pdev->dev, "vdd"); 2030411374bSLaurent Pinchart if (IS_ERR(sbridge->vdd)) { 2040411374bSLaurent Pinchart int ret = PTR_ERR(sbridge->vdd); 2050411374bSLaurent Pinchart if (ret == -EPROBE_DEFER) 2060411374bSLaurent Pinchart return -EPROBE_DEFER; 2070411374bSLaurent Pinchart sbridge->vdd = NULL; 2080411374bSLaurent Pinchart dev_dbg(&pdev->dev, "No vdd regulator found: %d\n", ret); 2090411374bSLaurent Pinchart } 2100411374bSLaurent Pinchart 2110411374bSLaurent Pinchart sbridge->ddc = simple_bridge_retrieve_ddc(&pdev->dev); 2120411374bSLaurent Pinchart if (IS_ERR(sbridge->ddc)) { 2130411374bSLaurent Pinchart if (PTR_ERR(sbridge->ddc) == -ENODEV) { 2140411374bSLaurent Pinchart dev_dbg(&pdev->dev, 2150411374bSLaurent Pinchart "No i2c bus specified. Disabling EDID readout\n"); 2160411374bSLaurent Pinchart sbridge->ddc = NULL; 2170411374bSLaurent Pinchart } else { 2180411374bSLaurent Pinchart dev_err(&pdev->dev, "Couldn't retrieve i2c bus\n"); 2190411374bSLaurent Pinchart return PTR_ERR(sbridge->ddc); 2200411374bSLaurent Pinchart } 2210411374bSLaurent Pinchart } 2220411374bSLaurent Pinchart 2230411374bSLaurent Pinchart sbridge->bridge.funcs = &simple_bridge_bridge_funcs; 2240411374bSLaurent Pinchart sbridge->bridge.of_node = pdev->dev.of_node; 225272378ecSLaurent Pinchart sbridge->bridge.timings = sbridge->info->timings; 2260411374bSLaurent Pinchart 2270411374bSLaurent Pinchart drm_bridge_add(&sbridge->bridge); 2280411374bSLaurent Pinchart 2290411374bSLaurent Pinchart return 0; 2300411374bSLaurent Pinchart } 2310411374bSLaurent Pinchart 2320411374bSLaurent Pinchart static int simple_bridge_remove(struct platform_device *pdev) 2330411374bSLaurent Pinchart { 2340411374bSLaurent Pinchart struct simple_bridge *sbridge = platform_get_drvdata(pdev); 2350411374bSLaurent Pinchart 2360411374bSLaurent Pinchart drm_bridge_remove(&sbridge->bridge); 2370411374bSLaurent Pinchart 2380411374bSLaurent Pinchart if (sbridge->ddc) 2390411374bSLaurent Pinchart i2c_put_adapter(sbridge->ddc); 2400411374bSLaurent Pinchart 2410411374bSLaurent Pinchart return 0; 2420411374bSLaurent Pinchart } 2430411374bSLaurent Pinchart 2440411374bSLaurent Pinchart /* 2450411374bSLaurent Pinchart * We assume the ADV7123 DAC is the "default" for historical reasons 2460411374bSLaurent Pinchart * Information taken from the ADV7123 datasheet, revision D. 2470411374bSLaurent Pinchart * NOTE: the ADV7123EP seems to have other timings and need a new timings 2480411374bSLaurent Pinchart * set if used. 2490411374bSLaurent Pinchart */ 2500411374bSLaurent Pinchart static const struct drm_bridge_timings default_bridge_timings = { 2510411374bSLaurent Pinchart /* Timing specifications, datasheet page 7 */ 2520411374bSLaurent Pinchart .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 2530411374bSLaurent Pinchart .setup_time_ps = 500, 2540411374bSLaurent Pinchart .hold_time_ps = 1500, 2550411374bSLaurent Pinchart }; 2560411374bSLaurent Pinchart 2570411374bSLaurent Pinchart /* 2580411374bSLaurent Pinchart * Information taken from the THS8134, THS8134A, THS8134B datasheet named 2590411374bSLaurent Pinchart * "SLVS205D", dated May 1990, revised March 2000. 2600411374bSLaurent Pinchart */ 2610411374bSLaurent Pinchart static const struct drm_bridge_timings ti_ths8134_bridge_timings = { 2620411374bSLaurent Pinchart /* From timing diagram, datasheet page 9 */ 2630411374bSLaurent Pinchart .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 2640411374bSLaurent Pinchart /* From datasheet, page 12 */ 2650411374bSLaurent Pinchart .setup_time_ps = 3000, 2660411374bSLaurent Pinchart /* I guess this means latched input */ 2670411374bSLaurent Pinchart .hold_time_ps = 0, 2680411374bSLaurent Pinchart }; 2690411374bSLaurent Pinchart 2700411374bSLaurent Pinchart /* 2710411374bSLaurent Pinchart * Information taken from the THS8135 datasheet named "SLAS343B", dated 2720411374bSLaurent Pinchart * May 2001, revised April 2013. 2730411374bSLaurent Pinchart */ 2740411374bSLaurent Pinchart static const struct drm_bridge_timings ti_ths8135_bridge_timings = { 2750411374bSLaurent Pinchart /* From timing diagram, datasheet page 14 */ 2760411374bSLaurent Pinchart .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE, 2770411374bSLaurent Pinchart /* From datasheet, page 16 */ 2780411374bSLaurent Pinchart .setup_time_ps = 2000, 2790411374bSLaurent Pinchart .hold_time_ps = 500, 2800411374bSLaurent Pinchart }; 2810411374bSLaurent Pinchart 2820411374bSLaurent Pinchart static const struct of_device_id simple_bridge_match[] = { 2830411374bSLaurent Pinchart { 2840411374bSLaurent Pinchart .compatible = "dumb-vga-dac", 285272378ecSLaurent Pinchart .data = &(const struct simple_bridge_info) { 286272378ecSLaurent Pinchart .connector_type = DRM_MODE_CONNECTOR_VGA, 2870411374bSLaurent Pinchart }, 288272378ecSLaurent Pinchart }, { 2890411374bSLaurent Pinchart .compatible = "adi,adv7123", 290272378ecSLaurent Pinchart .data = &(const struct simple_bridge_info) { 291272378ecSLaurent Pinchart .timings = &default_bridge_timings, 292272378ecSLaurent Pinchart .connector_type = DRM_MODE_CONNECTOR_VGA, 2930411374bSLaurent Pinchart }, 294272378ecSLaurent Pinchart }, { 2950411374bSLaurent Pinchart .compatible = "ti,ths8135", 296272378ecSLaurent Pinchart .data = &(const struct simple_bridge_info) { 297272378ecSLaurent Pinchart .timings = &ti_ths8135_bridge_timings, 298272378ecSLaurent Pinchart .connector_type = DRM_MODE_CONNECTOR_VGA, 2990411374bSLaurent Pinchart }, 300272378ecSLaurent Pinchart }, { 3010411374bSLaurent Pinchart .compatible = "ti,ths8134", 302272378ecSLaurent Pinchart .data = &(const struct simple_bridge_info) { 303272378ecSLaurent Pinchart .timings = &ti_ths8134_bridge_timings, 304272378ecSLaurent Pinchart .connector_type = DRM_MODE_CONNECTOR_VGA, 305272378ecSLaurent Pinchart }, 3060411374bSLaurent Pinchart }, 3070411374bSLaurent Pinchart {}, 3080411374bSLaurent Pinchart }; 3090411374bSLaurent Pinchart MODULE_DEVICE_TABLE(of, simple_bridge_match); 3100411374bSLaurent Pinchart 3110411374bSLaurent Pinchart static struct platform_driver simple_bridge_driver = { 3120411374bSLaurent Pinchart .probe = simple_bridge_probe, 3130411374bSLaurent Pinchart .remove = simple_bridge_remove, 3140411374bSLaurent Pinchart .driver = { 3150411374bSLaurent Pinchart .name = "simple-bridge", 3160411374bSLaurent Pinchart .of_match_table = simple_bridge_match, 3170411374bSLaurent Pinchart }, 3180411374bSLaurent Pinchart }; 3190411374bSLaurent Pinchart module_platform_driver(simple_bridge_driver); 3200411374bSLaurent Pinchart 3210411374bSLaurent Pinchart MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>"); 3220411374bSLaurent Pinchart MODULE_DESCRIPTION("Simple DRM bridge driver"); 3230411374bSLaurent Pinchart MODULE_LICENSE("GPL"); 324