diff options
author | Keith Packard <keithp@keithp.com> | 2009-05-30 23:42:27 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2009-06-12 01:37:27 -0400 |
commit | 61f11699e7a92d932b31ded3715ad4f70eb26ef2 (patch) | |
tree | 19b191e37195a955db4b8e206b346d6eb806c893 /drivers/gpu | |
parent | 7ff145593d808a371924652c8d6a15fb75ce2250 (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')
-rw-r--r-- | drivers/gpu/drm/drm_edid.c | 74 |
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 | } |
585 | EXPORT_SYMBOL(drm_do_probe_ddc_edid); | 585 | EXPORT_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 | */ | ||
598 | static 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 | |||
659 | static int drm_ddc_read_edid(struct drm_connector *connector, | 587 | static 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)); |