diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index ded122c1ae2d..f3ef6bfd8ffc 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -1402,10 +1402,8 @@ static enum drm_connector_status intel_sdvo_detect(struct drm_connector *connect | |||
1402 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) | 1402 | static void intel_sdvo_get_ddc_modes(struct drm_connector *connector) |
1403 | { | 1403 | { |
1404 | struct intel_output *intel_output = to_intel_output(connector); | 1404 | struct intel_output *intel_output = to_intel_output(connector); |
1405 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1406 | 1405 | ||
1407 | /* set the bus switch and get the modes */ | 1406 | /* set the bus switch and get the modes */ |
1408 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1409 | intel_ddc_get_modes(intel_output); | 1407 | intel_ddc_get_modes(intel_output); |
1410 | 1408 | ||
1411 | #if 0 | 1409 | #if 0 |
@@ -1601,6 +1599,9 @@ static void intel_sdvo_destroy(struct drm_connector *connector) | |||
1601 | 1599 | ||
1602 | if (intel_output->i2c_bus) | 1600 | if (intel_output->i2c_bus) |
1603 | intel_i2c_destroy(intel_output->i2c_bus); | 1601 | intel_i2c_destroy(intel_output->i2c_bus); |
1602 | if (intel_output->ddc_bus) | ||
1603 | intel_i2c_destroy(intel_output->ddc_bus); | ||
1604 | |||
1604 | drm_sysfs_connector_remove(connector); | 1605 | drm_sysfs_connector_remove(connector); |
1605 | drm_connector_cleanup(connector); | 1606 | drm_connector_cleanup(connector); |
1606 | kfree(intel_output); | 1607 | kfree(intel_output); |
@@ -1697,12 +1698,56 @@ intel_sdvo_get_digital_encoding_mode(struct intel_output *output) | |||
1697 | return true; | 1698 | return true; |
1698 | } | 1699 | } |
1699 | 1700 | ||
1701 | static struct intel_output * | ||
1702 | intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) | ||
1703 | { | ||
1704 | struct drm_device *dev = chan->drm_dev; | ||
1705 | struct drm_connector *connector; | ||
1706 | struct intel_output *intel_output = NULL; | ||
1707 | |||
1708 | list_for_each_entry(connector, | ||
1709 | &dev->mode_config.connector_list, head) { | ||
1710 | if (to_intel_output(connector)->ddc_bus == chan) { | ||
1711 | intel_output = to_intel_output(connector); | ||
1712 | break; | ||
1713 | } | ||
1714 | } | ||
1715 | return intel_output; | ||
1716 | } | ||
1717 | |||
1718 | static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | ||
1719 | struct i2c_msg msgs[], int num) | ||
1720 | { | ||
1721 | struct intel_output *intel_output; | ||
1722 | struct intel_sdvo_priv *sdvo_priv; | ||
1723 | struct i2c_algo_bit_data *algo_data; | ||
1724 | struct i2c_algorithm *algo; | ||
1725 | |||
1726 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | ||
1727 | intel_output = | ||
1728 | intel_sdvo_chan_to_intel_output( | ||
1729 | (struct intel_i2c_chan *)(algo_data->data)); | ||
1730 | if (intel_output == NULL) | ||
1731 | return -EINVAL; | ||
1732 | |||
1733 | sdvo_priv = intel_output->dev_priv; | ||
1734 | algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; | ||
1735 | |||
1736 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1737 | return algo->master_xfer(i2c_adap, msgs, num); | ||
1738 | } | ||
1739 | |||
1740 | static struct i2c_algorithm intel_sdvo_i2c_bit_algo = { | ||
1741 | .master_xfer = intel_sdvo_master_xfer, | ||
1742 | }; | ||
1743 | |||
1700 | bool intel_sdvo_init(struct drm_device *dev, int output_device) | 1744 | bool intel_sdvo_init(struct drm_device *dev, int output_device) |
1701 | { | 1745 | { |
1702 | struct drm_connector *connector; | 1746 | struct drm_connector *connector; |
1703 | struct intel_output *intel_output; | 1747 | struct intel_output *intel_output; |
1704 | struct intel_sdvo_priv *sdvo_priv; | 1748 | struct intel_sdvo_priv *sdvo_priv; |
1705 | struct intel_i2c_chan *i2cbus = NULL; | 1749 | struct intel_i2c_chan *i2cbus = NULL; |
1750 | struct intel_i2c_chan *ddcbus = NULL; | ||
1706 | int connector_type; | 1751 | int connector_type; |
1707 | u8 ch[0x40]; | 1752 | u8 ch[0x40]; |
1708 | int i; | 1753 | int i; |
@@ -1748,6 +1793,20 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1748 | } | 1793 | } |
1749 | } | 1794 | } |
1750 | 1795 | ||
1796 | /* setup the DDC bus. */ | ||
1797 | if (output_device == SDVOB) | ||
1798 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | ||
1799 | else | ||
1800 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | ||
1801 | |||
1802 | if (ddcbus == NULL) | ||
1803 | goto err_i2c; | ||
1804 | |||
1805 | intel_sdvo_i2c_bit_algo.functionality = | ||
1806 | intel_output->i2c_bus->adapter.algo->functionality; | ||
1807 | ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; | ||
1808 | intel_output->ddc_bus = ddcbus; | ||
1809 | |||
1751 | /* In defaut case sdvo lvds is false */ | 1810 | /* In defaut case sdvo lvds is false */ |
1752 | sdvo_priv->is_lvds = false; | 1811 | sdvo_priv->is_lvds = false; |
1753 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); | 1812 | intel_sdvo_get_capabilities(intel_output, &sdvo_priv->caps); |
@@ -1862,11 +1921,11 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1862 | sdvo_priv->caps.output_flags & | 1921 | sdvo_priv->caps.output_flags & |
1863 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); | 1922 | (SDVO_OUTPUT_TMDS1 | SDVO_OUTPUT_RGB1) ? 'Y' : 'N'); |
1864 | 1923 | ||
1865 | intel_output->ddc_bus = i2cbus; | ||
1866 | |||
1867 | return true; | 1924 | return true; |
1868 | 1925 | ||
1869 | err_i2c: | 1926 | err_i2c: |
1927 | if (ddcbus != NULL) | ||
1928 | intel_i2c_destroy(intel_output->ddc_bus); | ||
1870 | intel_i2c_destroy(intel_output->i2c_bus); | 1929 | intel_i2c_destroy(intel_output->i2c_bus); |
1871 | err_inteloutput: | 1930 | err_inteloutput: |
1872 | kfree(intel_output); | 1931 | kfree(intel_output); |