root/drivers/gpu/drm/bridge/ti-tfp410.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. drm_bridge_to_tfp410
  2. drm_connector_to_tfp410
  3. tfp410_get_modes
  4. tfp410_connector_detect
  5. tfp410_attach
  6. tfp410_enable
  7. tfp410_disable
  8. tfp410_hpd_work_func
  9. tfp410_hpd_irq_thread
  10. tfp410_parse_timings
  11. tfp410_get_connector_properties
  12. tfp410_init
  13. tfp410_fini
  14. tfp410_probe
  15. tfp410_remove
  16. tfp410_i2c_probe
  17. tfp410_i2c_remove
  18. tfp410_module_init
  19. tfp410_module_exit

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2016 Texas Instruments
   4  * Author: Jyri Sarha <jsarha@ti.com>
   5  */
   6 
   7 #include <linux/delay.h>
   8 #include <linux/fwnode.h>
   9 #include <linux/gpio/consumer.h>
  10 #include <linux/i2c.h>
  11 #include <linux/irq.h>
  12 #include <linux/module.h>
  13 #include <linux/of_graph.h>
  14 #include <linux/platform_device.h>
  15 
  16 #include <drm/drm_atomic_helper.h>
  17 #include <drm/drm_crtc.h>
  18 #include <drm/drm_print.h>
  19 #include <drm/drm_probe_helper.h>
  20 
  21 #define HOTPLUG_DEBOUNCE_MS             1100
  22 
  23 struct tfp410 {
  24         struct drm_bridge       bridge;
  25         struct drm_connector    connector;
  26         unsigned int            connector_type;
  27 
  28         u32                     bus_format;
  29         struct i2c_adapter      *ddc;
  30         struct gpio_desc        *hpd;
  31         int                     hpd_irq;
  32         struct delayed_work     hpd_work;
  33         struct gpio_desc        *powerdown;
  34 
  35         struct drm_bridge_timings timings;
  36 
  37         struct device *dev;
  38 };
  39 
  40 static inline struct tfp410 *
  41 drm_bridge_to_tfp410(struct drm_bridge *bridge)
  42 {
  43         return container_of(bridge, struct tfp410, bridge);
  44 }
  45 
  46 static inline struct tfp410 *
  47 drm_connector_to_tfp410(struct drm_connector *connector)
  48 {
  49         return container_of(connector, struct tfp410, connector);
  50 }
  51 
  52 static int tfp410_get_modes(struct drm_connector *connector)
  53 {
  54         struct tfp410 *dvi = drm_connector_to_tfp410(connector);
  55         struct edid *edid;
  56         int ret;
  57 
  58         if (!dvi->ddc)
  59                 goto fallback;
  60 
  61         edid = drm_get_edid(connector, dvi->ddc);
  62         if (!edid) {
  63                 DRM_INFO("EDID read failed. Fallback to standard modes\n");
  64                 goto fallback;
  65         }
  66 
  67         drm_connector_update_edid_property(connector, edid);
  68 
  69         ret = drm_add_edid_modes(connector, edid);
  70 
  71         kfree(edid);
  72 
  73         return ret;
  74 
  75 fallback:
  76         /* No EDID, fallback on the XGA standard modes */
  77         ret = drm_add_modes_noedid(connector, 1920, 1200);
  78 
  79         /* And prefer a mode pretty much anything can handle */
  80         drm_set_preferred_mode(connector, 1024, 768);
  81 
  82         return ret;
  83 }
  84 
  85 static const struct drm_connector_helper_funcs tfp410_con_helper_funcs = {
  86         .get_modes      = tfp410_get_modes,
  87 };
  88 
  89 static enum drm_connector_status
  90 tfp410_connector_detect(struct drm_connector *connector, bool force)
  91 {
  92         struct tfp410 *dvi = drm_connector_to_tfp410(connector);
  93 
  94         if (dvi->hpd) {
  95                 if (gpiod_get_value_cansleep(dvi->hpd))
  96                         return connector_status_connected;
  97                 else
  98                         return connector_status_disconnected;
  99         }
 100 
 101         if (dvi->ddc) {
 102                 if (drm_probe_ddc(dvi->ddc))
 103                         return connector_status_connected;
 104                 else
 105                         return connector_status_disconnected;
 106         }
 107 
 108         return connector_status_unknown;
 109 }
 110 
 111 static const struct drm_connector_funcs tfp410_con_funcs = {
 112         .detect                 = tfp410_connector_detect,
 113         .fill_modes             = drm_helper_probe_single_connector_modes,
 114         .destroy                = drm_connector_cleanup,
 115         .reset                  = drm_atomic_helper_connector_reset,
 116         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 117         .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state,
 118 };
 119 
 120 static int tfp410_attach(struct drm_bridge *bridge)
 121 {
 122         struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
 123         int ret;
 124 
 125         if (!bridge->encoder) {
 126                 dev_err(dvi->dev, "Missing encoder\n");
 127                 return -ENODEV;
 128         }
 129 
 130         if (dvi->hpd_irq >= 0)
 131                 dvi->connector.polled = DRM_CONNECTOR_POLL_HPD;
 132         else
 133                 dvi->connector.polled = DRM_CONNECTOR_POLL_CONNECT | DRM_CONNECTOR_POLL_DISCONNECT;
 134 
 135         drm_connector_helper_add(&dvi->connector,
 136                                  &tfp410_con_helper_funcs);
 137         ret = drm_connector_init_with_ddc(bridge->dev, &dvi->connector,
 138                                           &tfp410_con_funcs,
 139                                           dvi->connector_type,
 140                                           dvi->ddc);
 141         if (ret) {
 142                 dev_err(dvi->dev, "drm_connector_init() failed: %d\n", ret);
 143                 return ret;
 144         }
 145 
 146         drm_display_info_set_bus_formats(&dvi->connector.display_info,
 147                                          &dvi->bus_format, 1);
 148 
 149         drm_connector_attach_encoder(&dvi->connector,
 150                                           bridge->encoder);
 151 
 152         return 0;
 153 }
 154 
 155 static void tfp410_enable(struct drm_bridge *bridge)
 156 {
 157         struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
 158 
 159         gpiod_set_value_cansleep(dvi->powerdown, 0);
 160 }
 161 
 162 static void tfp410_disable(struct drm_bridge *bridge)
 163 {
 164         struct tfp410 *dvi = drm_bridge_to_tfp410(bridge);
 165 
 166         gpiod_set_value_cansleep(dvi->powerdown, 1);
 167 }
 168 
 169 static const struct drm_bridge_funcs tfp410_bridge_funcs = {
 170         .attach         = tfp410_attach,
 171         .enable         = tfp410_enable,
 172         .disable        = tfp410_disable,
 173 };
 174 
 175 static void tfp410_hpd_work_func(struct work_struct *work)
 176 {
 177         struct tfp410 *dvi;
 178 
 179         dvi = container_of(work, struct tfp410, hpd_work.work);
 180 
 181         if (dvi->bridge.dev)
 182                 drm_helper_hpd_irq_event(dvi->bridge.dev);
 183 }
 184 
 185 static irqreturn_t tfp410_hpd_irq_thread(int irq, void *arg)
 186 {
 187         struct tfp410 *dvi = arg;
 188 
 189         mod_delayed_work(system_wq, &dvi->hpd_work,
 190                         msecs_to_jiffies(HOTPLUG_DEBOUNCE_MS));
 191 
 192         return IRQ_HANDLED;
 193 }
 194 
 195 static const struct drm_bridge_timings tfp410_default_timings = {
 196         .input_bus_flags = DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
 197                          | DRM_BUS_FLAG_DE_HIGH,
 198         .setup_time_ps = 1200,
 199         .hold_time_ps = 1300,
 200 };
 201 
 202 static int tfp410_parse_timings(struct tfp410 *dvi, bool i2c)
 203 {
 204         struct drm_bridge_timings *timings = &dvi->timings;
 205         struct device_node *ep;
 206         u32 pclk_sample = 0;
 207         u32 bus_width = 24;
 208         s32 deskew = 0;
 209 
 210         /* Start with defaults. */
 211         *timings = tfp410_default_timings;
 212 
 213         if (i2c)
 214                 /*
 215                  * In I2C mode timings are configured through the I2C interface.
 216                  * As the driver doesn't support I2C configuration yet, we just
 217                  * go with the defaults (BSEL=1, DSEL=1, DKEN=0, EDGE=1).
 218                  */
 219                 return 0;
 220 
 221         /*
 222          * In non-I2C mode, timings are configured through the BSEL, DSEL, DKEN
 223          * and EDGE pins. They are specified in DT through endpoint properties
 224          * and vendor-specific properties.
 225          */
 226         ep = of_graph_get_endpoint_by_regs(dvi->dev->of_node, 0, 0);
 227         if (!ep)
 228                 return -EINVAL;
 229 
 230         /* Get the sampling edge from the endpoint. */
 231         of_property_read_u32(ep, "pclk-sample", &pclk_sample);
 232         of_property_read_u32(ep, "bus-width", &bus_width);
 233         of_node_put(ep);
 234 
 235         timings->input_bus_flags = DRM_BUS_FLAG_DE_HIGH;
 236 
 237         switch (pclk_sample) {
 238         case 0:
 239                 timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_NEGEDGE
 240                                          |  DRM_BUS_FLAG_SYNC_SAMPLE_NEGEDGE;
 241                 break;
 242         case 1:
 243                 timings->input_bus_flags |= DRM_BUS_FLAG_PIXDATA_SAMPLE_POSEDGE
 244                                          |  DRM_BUS_FLAG_SYNC_SAMPLE_POSEDGE;
 245                 break;
 246         default:
 247                 return -EINVAL;
 248         }
 249 
 250         switch (bus_width) {
 251         case 12:
 252                 dvi->bus_format = MEDIA_BUS_FMT_RGB888_2X12_LE;
 253                 break;
 254         case 24:
 255                 dvi->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
 256                 break;
 257         default:
 258                 return -EINVAL;
 259         }
 260 
 261         /* Get the setup and hold time from vendor-specific properties. */
 262         of_property_read_u32(dvi->dev->of_node, "ti,deskew", (u32 *)&deskew);
 263         if (deskew < -4 || deskew > 3)
 264                 return -EINVAL;
 265 
 266         timings->setup_time_ps = min(0, 1200 - 350 * deskew);
 267         timings->hold_time_ps = min(0, 1300 + 350 * deskew);
 268 
 269         return 0;
 270 }
 271 
 272 static int tfp410_get_connector_properties(struct tfp410 *dvi)
 273 {
 274         struct device_node *connector_node, *ddc_phandle;
 275         int ret = 0;
 276 
 277         /* port@1 is the connector node */
 278         connector_node = of_graph_get_remote_node(dvi->dev->of_node, 1, -1);
 279         if (!connector_node)
 280                 return -ENODEV;
 281 
 282         if (of_device_is_compatible(connector_node, "hdmi-connector"))
 283                 dvi->connector_type = DRM_MODE_CONNECTOR_HDMIA;
 284         else
 285                 dvi->connector_type = DRM_MODE_CONNECTOR_DVID;
 286 
 287         dvi->hpd = fwnode_get_named_gpiod(&connector_node->fwnode,
 288                                         "hpd-gpios", 0, GPIOD_IN, "hpd");
 289         if (IS_ERR(dvi->hpd)) {
 290                 ret = PTR_ERR(dvi->hpd);
 291                 dvi->hpd = NULL;
 292                 if (ret == -ENOENT)
 293                         ret = 0;
 294                 else
 295                         goto fail;
 296         }
 297 
 298         ddc_phandle = of_parse_phandle(connector_node, "ddc-i2c-bus", 0);
 299         if (!ddc_phandle)
 300                 goto fail;
 301 
 302         dvi->ddc = of_get_i2c_adapter_by_node(ddc_phandle);
 303         if (dvi->ddc)
 304                 dev_info(dvi->dev, "Connector's ddc i2c bus found\n");
 305         else
 306                 ret = -EPROBE_DEFER;
 307 
 308         of_node_put(ddc_phandle);
 309 
 310 fail:
 311         of_node_put(connector_node);
 312         return ret;
 313 }
 314 
 315 static int tfp410_init(struct device *dev, bool i2c)
 316 {
 317         struct tfp410 *dvi;
 318         int ret;
 319 
 320         if (!dev->of_node) {
 321                 dev_err(dev, "device-tree data is missing\n");
 322                 return -ENXIO;
 323         }
 324 
 325         dvi = devm_kzalloc(dev, sizeof(*dvi), GFP_KERNEL);
 326         if (!dvi)
 327                 return -ENOMEM;
 328         dev_set_drvdata(dev, dvi);
 329 
 330         dvi->bridge.funcs = &tfp410_bridge_funcs;
 331         dvi->bridge.of_node = dev->of_node;
 332         dvi->bridge.timings = &dvi->timings;
 333         dvi->dev = dev;
 334 
 335         ret = tfp410_parse_timings(dvi, i2c);
 336         if (ret)
 337                 goto fail;
 338 
 339         ret = tfp410_get_connector_properties(dvi);
 340         if (ret)
 341                 goto fail;
 342 
 343         dvi->powerdown = devm_gpiod_get_optional(dev, "powerdown",
 344                                                  GPIOD_OUT_HIGH);
 345         if (IS_ERR(dvi->powerdown)) {
 346                 dev_err(dev, "failed to parse powerdown gpio\n");
 347                 return PTR_ERR(dvi->powerdown);
 348         }
 349 
 350         if (dvi->hpd)
 351                 dvi->hpd_irq = gpiod_to_irq(dvi->hpd);
 352         else
 353                 dvi->hpd_irq = -ENXIO;
 354 
 355         if (dvi->hpd_irq >= 0) {
 356                 INIT_DELAYED_WORK(&dvi->hpd_work, tfp410_hpd_work_func);
 357 
 358                 ret = devm_request_threaded_irq(dev, dvi->hpd_irq,
 359                         NULL, tfp410_hpd_irq_thread, IRQF_TRIGGER_RISING |
 360                         IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
 361                         "hdmi-hpd", dvi);
 362                 if (ret) {
 363                         DRM_ERROR("failed to register hpd interrupt\n");
 364                         goto fail;
 365                 }
 366         }
 367 
 368         drm_bridge_add(&dvi->bridge);
 369 
 370         return 0;
 371 fail:
 372         i2c_put_adapter(dvi->ddc);
 373         if (dvi->hpd)
 374                 gpiod_put(dvi->hpd);
 375         return ret;
 376 }
 377 
 378 static int tfp410_fini(struct device *dev)
 379 {
 380         struct tfp410 *dvi = dev_get_drvdata(dev);
 381 
 382         if (dvi->hpd_irq >= 0)
 383                 cancel_delayed_work_sync(&dvi->hpd_work);
 384 
 385         drm_bridge_remove(&dvi->bridge);
 386 
 387         if (dvi->ddc)
 388                 i2c_put_adapter(dvi->ddc);
 389         if (dvi->hpd)
 390                 gpiod_put(dvi->hpd);
 391 
 392         return 0;
 393 }
 394 
 395 static int tfp410_probe(struct platform_device *pdev)
 396 {
 397         return tfp410_init(&pdev->dev, false);
 398 }
 399 
 400 static int tfp410_remove(struct platform_device *pdev)
 401 {
 402         return tfp410_fini(&pdev->dev);
 403 }
 404 
 405 static const struct of_device_id tfp410_match[] = {
 406         { .compatible = "ti,tfp410" },
 407         {},
 408 };
 409 MODULE_DEVICE_TABLE(of, tfp410_match);
 410 
 411 static struct platform_driver tfp410_platform_driver = {
 412         .probe  = tfp410_probe,
 413         .remove = tfp410_remove,
 414         .driver = {
 415                 .name           = "tfp410-bridge",
 416                 .of_match_table = tfp410_match,
 417         },
 418 };
 419 
 420 #if IS_ENABLED(CONFIG_I2C)
 421 /* There is currently no i2c functionality. */
 422 static int tfp410_i2c_probe(struct i2c_client *client,
 423                             const struct i2c_device_id *id)
 424 {
 425         int reg;
 426 
 427         if (!client->dev.of_node ||
 428             of_property_read_u32(client->dev.of_node, "reg", &reg)) {
 429                 dev_err(&client->dev,
 430                         "Can't get i2c reg property from device-tree\n");
 431                 return -ENXIO;
 432         }
 433 
 434         return tfp410_init(&client->dev, true);
 435 }
 436 
 437 static int tfp410_i2c_remove(struct i2c_client *client)
 438 {
 439         return tfp410_fini(&client->dev);
 440 }
 441 
 442 static const struct i2c_device_id tfp410_i2c_ids[] = {
 443         { "tfp410", 0 },
 444         { }
 445 };
 446 MODULE_DEVICE_TABLE(i2c, tfp410_i2c_ids);
 447 
 448 static struct i2c_driver tfp410_i2c_driver = {
 449         .driver = {
 450                 .name   = "tfp410",
 451                 .of_match_table = of_match_ptr(tfp410_match),
 452         },
 453         .id_table       = tfp410_i2c_ids,
 454         .probe          = tfp410_i2c_probe,
 455         .remove         = tfp410_i2c_remove,
 456 };
 457 #endif /* IS_ENABLED(CONFIG_I2C) */
 458 
 459 static struct {
 460         uint i2c:1;
 461         uint platform:1;
 462 }  tfp410_registered_driver;
 463 
 464 static int __init tfp410_module_init(void)
 465 {
 466         int ret;
 467 
 468 #if IS_ENABLED(CONFIG_I2C)
 469         ret = i2c_add_driver(&tfp410_i2c_driver);
 470         if (ret)
 471                 pr_err("%s: registering i2c driver failed: %d",
 472                        __func__, ret);
 473         else
 474                 tfp410_registered_driver.i2c = 1;
 475 #endif
 476 
 477         ret = platform_driver_register(&tfp410_platform_driver);
 478         if (ret)
 479                 pr_err("%s: registering platform driver failed: %d",
 480                        __func__, ret);
 481         else
 482                 tfp410_registered_driver.platform = 1;
 483 
 484         if (tfp410_registered_driver.i2c ||
 485             tfp410_registered_driver.platform)
 486                 return 0;
 487 
 488         return ret;
 489 }
 490 module_init(tfp410_module_init);
 491 
 492 static void __exit tfp410_module_exit(void)
 493 {
 494 #if IS_ENABLED(CONFIG_I2C)
 495         if (tfp410_registered_driver.i2c)
 496                 i2c_del_driver(&tfp410_i2c_driver);
 497 #endif
 498         if (tfp410_registered_driver.platform)
 499                 platform_driver_unregister(&tfp410_platform_driver);
 500 }
 501 module_exit(tfp410_module_exit);
 502 
 503 MODULE_AUTHOR("Jyri Sarha <jsarha@ti.com>");
 504 MODULE_DESCRIPTION("TI TFP410 DVI bridge driver");
 505 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */