aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/drm_edid.c
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2009-05-30 23:42:27 -0400
committerDave Airlie <airlied@redhat.com>2009-06-12 01:37:27 -0400
commit61f11699e7a92d932b31ded3715ad4f70eb26ef2 (patch)
tree19b191e37195a955db4b8e206b346d6eb806c893 /drivers/gpu/drm/drm_edid.c
parent7ff145593d808a371924652c8d6a15fb75ce2250 (diff)
drm: Eliminate magic I2C frobbing when reading EDID
This code depends on the underlying I2C adapter using the bit-banging algo, which may not be the case. If specific encoders require this mechanism, they should build a custom I2C algo that implements this workaround, rather than having it in the general path. Signed-off-by: Keith Packard <keithp@keithp.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/drm_edid.c')
-rw-r--r--drivers/gpu/drm/drm_edid.c74
1 files changed, 1 insertions, 73 deletions
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index ca9c61656714..c4d9b3308d42 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -584,85 +584,13 @@ int drm_do_probe_ddc_edid(struct i2c_adapter *adapter,
584} 584}
585EXPORT_SYMBOL(drm_do_probe_ddc_edid); 585EXPORT_SYMBOL(drm_do_probe_ddc_edid);
586 586
587/**
588 * Get EDID information.
589 *
590 * \param adapter : i2c device adaptor.
591 * \param buf : EDID data buffer to be filled
592 * \param len : EDID data buffer length
593 * \return 0 on success or -1 on failure.
594 *
595 * Initialize DDC, then fetch EDID information
596 * by calling drm_do_probe_ddc_edid function.
597 */
598static int drm_ddc_read(struct i2c_adapter *adapter,
599 unsigned char *buf, int len)
600{
601 struct i2c_algo_bit_data *algo_data = adapter->algo_data;
602 int i, j;
603 int ret = -1;
604
605 algo_data->setscl(algo_data->data, 1);
606
607 for (i = 0; i < 1; i++) {
608 /* For some old monitors we need the
609 * following process to initialize/stop DDC
610 */
611 algo_data->setsda(algo_data->data, 1);
612 msleep(13);
613
614 algo_data->setscl(algo_data->data, 1);
615 for (j = 0; j < 5; j++) {
616 msleep(10);
617 if (algo_data->getscl(algo_data->data))
618 break;
619 }
620 if (j == 5)
621 continue;
622
623 algo_data->setsda(algo_data->data, 0);
624 msleep(15);
625 algo_data->setscl(algo_data->data, 0);
626 msleep(15);
627 algo_data->setsda(algo_data->data, 1);
628 msleep(15);
629
630 /* Do the real work */
631 ret = drm_do_probe_ddc_edid(adapter, buf, len);
632 algo_data->setsda(algo_data->data, 0);
633 algo_data->setscl(algo_data->data, 0);
634 msleep(15);
635
636 algo_data->setscl(algo_data->data, 1);
637 for (j = 0; j < 10; j++) {
638 msleep(10);
639 if (algo_data->getscl(algo_data->data))
640 break;
641 }
642
643 algo_data->setsda(algo_data->data, 1);
644 msleep(15);
645 algo_data->setscl(algo_data->data, 0);
646 algo_data->setsda(algo_data->data, 0);
647 if (ret == 0)
648 break;
649 }
650 /* Release the DDC lines when done or the Apple Cinema HD display
651 * will switch off
652 */
653 algo_data->setsda(algo_data->data, 1);
654 algo_data->setscl(algo_data->data, 1);
655
656 return ret;
657}
658
659static int drm_ddc_read_edid(struct drm_connector *connector, 587static int drm_ddc_read_edid(struct drm_connector *connector,
660 struct i2c_adapter *adapter, 588 struct i2c_adapter *adapter,
661 char *buf, int len) 589 char *buf, int len)
662{ 590{
663 int ret; 591 int ret;
664 592
665 ret = drm_ddc_read(adapter, buf, len); 593 ret = drm_do_probe_ddc_edid(adapter, buf, len);
666 if (ret != 0) { 594 if (ret != 0) {
667 dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n", 595 dev_info(&connector->dev->pdev->dev, "%s: no EDID data\n",
668 drm_get_connector_name(connector)); 596 drm_get_connector_name(connector));