diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_sdvo.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_sdvo.c | 72 |
1 files changed, 30 insertions, 42 deletions
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 9a00adb3a508..f03473779feb 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -38,8 +38,7 @@ | |||
38 | #undef SDVO_DEBUG | 38 | #undef SDVO_DEBUG |
39 | #define I915_SDVO "i915_sdvo" | 39 | #define I915_SDVO "i915_sdvo" |
40 | struct intel_sdvo_priv { | 40 | struct intel_sdvo_priv { |
41 | struct intel_i2c_chan *i2c_bus; | 41 | u8 slave_addr; |
42 | int slaveaddr; | ||
43 | 42 | ||
44 | /* Register for the SDVO device: SDVOB or SDVOC */ | 43 | /* Register for the SDVO device: SDVOB or SDVOC */ |
45 | int output_device; | 44 | int output_device; |
@@ -146,13 +145,13 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
146 | 145 | ||
147 | struct i2c_msg msgs[] = { | 146 | struct i2c_msg msgs[] = { |
148 | { | 147 | { |
149 | .addr = sdvo_priv->i2c_bus->slave_addr, | 148 | .addr = sdvo_priv->slave_addr >> 1, |
150 | .flags = 0, | 149 | .flags = 0, |
151 | .len = 1, | 150 | .len = 1, |
152 | .buf = out_buf, | 151 | .buf = out_buf, |
153 | }, | 152 | }, |
154 | { | 153 | { |
155 | .addr = sdvo_priv->i2c_bus->slave_addr, | 154 | .addr = sdvo_priv->slave_addr >> 1, |
156 | .flags = I2C_M_RD, | 155 | .flags = I2C_M_RD, |
157 | .len = 1, | 156 | .len = 1, |
158 | .buf = buf, | 157 | .buf = buf, |
@@ -162,7 +161,7 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
162 | out_buf[0] = addr; | 161 | out_buf[0] = addr; |
163 | out_buf[1] = 0; | 162 | out_buf[1] = 0; |
164 | 163 | ||
165 | if ((ret = i2c_transfer(&sdvo_priv->i2c_bus->adapter, msgs, 2)) == 2) | 164 | if ((ret = i2c_transfer(intel_output->i2c_bus, msgs, 2)) == 2) |
166 | { | 165 | { |
167 | *ch = buf[0]; | 166 | *ch = buf[0]; |
168 | return true; | 167 | return true; |
@@ -175,10 +174,11 @@ static bool intel_sdvo_read_byte(struct intel_output *intel_output, u8 addr, | |||
175 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | 174 | static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, |
176 | u8 ch) | 175 | u8 ch) |
177 | { | 176 | { |
177 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
178 | u8 out_buf[2]; | 178 | u8 out_buf[2]; |
179 | struct i2c_msg msgs[] = { | 179 | struct i2c_msg msgs[] = { |
180 | { | 180 | { |
181 | .addr = intel_output->i2c_bus->slave_addr, | 181 | .addr = sdvo_priv->slave_addr >> 1, |
182 | .flags = 0, | 182 | .flags = 0, |
183 | .len = 2, | 183 | .len = 2, |
184 | .buf = out_buf, | 184 | .buf = out_buf, |
@@ -188,7 +188,7 @@ static bool intel_sdvo_write_byte(struct intel_output *intel_output, int addr, | |||
188 | out_buf[0] = addr; | 188 | out_buf[0] = addr; |
189 | out_buf[1] = ch; | 189 | out_buf[1] = ch; |
190 | 190 | ||
191 | if (i2c_transfer(&intel_output->i2c_bus->adapter, msgs, 1) == 1) | 191 | if (i2c_transfer(intel_output->i2c_bus, msgs, 1) == 1) |
192 | { | 192 | { |
193 | return true; | 193 | return true; |
194 | } | 194 | } |
@@ -1369,9 +1369,8 @@ intel_sdvo_hdmi_sink_detect(struct drm_connector *connector) | |||
1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | 1369 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; |
1370 | struct edid *edid = NULL; | 1370 | struct edid *edid = NULL; |
1371 | 1371 | ||
1372 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1373 | edid = drm_get_edid(&intel_output->base, | 1372 | edid = drm_get_edid(&intel_output->base, |
1374 | &intel_output->ddc_bus->adapter); | 1373 | intel_output->ddc_bus); |
1375 | if (edid != NULL) { | 1374 | if (edid != NULL) { |
1376 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); | 1375 | sdvo_priv->is_hdmi = drm_detect_hdmi_monitor(edid); |
1377 | kfree(edid); | 1376 | kfree(edid); |
@@ -1549,7 +1548,6 @@ static void intel_sdvo_get_tv_modes(struct drm_connector *connector) | |||
1549 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | 1548 | static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) |
1550 | { | 1549 | { |
1551 | struct intel_output *intel_output = to_intel_output(connector); | 1550 | struct intel_output *intel_output = to_intel_output(connector); |
1552 | struct intel_sdvo_priv *sdvo_priv = intel_output->dev_priv; | ||
1553 | struct drm_i915_private *dev_priv = connector->dev->dev_private; | 1551 | struct drm_i915_private *dev_priv = connector->dev->dev_private; |
1554 | 1552 | ||
1555 | /* | 1553 | /* |
@@ -1557,8 +1555,6 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) | |||
1557 | * Assume that the preferred modes are | 1555 | * Assume that the preferred modes are |
1558 | * arranged in priority order. | 1556 | * arranged in priority order. |
1559 | */ | 1557 | */ |
1560 | /* set the bus switch and get the modes */ | ||
1561 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | ||
1562 | intel_ddc_get_modes(intel_output); | 1558 | intel_ddc_get_modes(intel_output); |
1563 | if (list_empty(&connector->probed_modes) == false) | 1559 | if (list_empty(&connector->probed_modes) == false) |
1564 | return; | 1560 | return; |
@@ -1709,7 +1705,7 @@ intel_sdvo_chan_to_intel_output(struct intel_i2c_chan *chan) | |||
1709 | 1705 | ||
1710 | list_for_each_entry(connector, | 1706 | list_for_each_entry(connector, |
1711 | &dev->mode_config.connector_list, head) { | 1707 | &dev->mode_config.connector_list, head) { |
1712 | if (to_intel_output(connector)->ddc_bus == chan) { | 1708 | if (to_intel_output(connector)->ddc_bus == &chan->adapter) { |
1713 | intel_output = to_intel_output(connector); | 1709 | intel_output = to_intel_output(connector); |
1714 | break; | 1710 | break; |
1715 | } | 1711 | } |
@@ -1723,7 +1719,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1723 | struct intel_output *intel_output; | 1719 | struct intel_output *intel_output; |
1724 | struct intel_sdvo_priv *sdvo_priv; | 1720 | struct intel_sdvo_priv *sdvo_priv; |
1725 | struct i2c_algo_bit_data *algo_data; | 1721 | struct i2c_algo_bit_data *algo_data; |
1726 | struct i2c_algorithm *algo; | 1722 | const struct i2c_algorithm *algo; |
1727 | 1723 | ||
1728 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; | 1724 | algo_data = (struct i2c_algo_bit_data *)i2c_adap->algo_data; |
1729 | intel_output = | 1725 | intel_output = |
@@ -1733,7 +1729,7 @@ static int intel_sdvo_master_xfer(struct i2c_adapter *i2c_adap, | |||
1733 | return -EINVAL; | 1729 | return -EINVAL; |
1734 | 1730 | ||
1735 | sdvo_priv = intel_output->dev_priv; | 1731 | sdvo_priv = intel_output->dev_priv; |
1736 | algo = (struct i2c_algorithm *)intel_output->i2c_bus->adapter.algo; | 1732 | algo = intel_output->i2c_bus->algo; |
1737 | 1733 | ||
1738 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); | 1734 | intel_sdvo_set_control_bus_switch(intel_output, sdvo_priv->ddc_bus); |
1739 | return algo->master_xfer(i2c_adap, msgs, num); | 1735 | return algo->master_xfer(i2c_adap, msgs, num); |
@@ -1785,13 +1781,11 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1785 | struct drm_connector *connector; | 1781 | struct drm_connector *connector; |
1786 | struct intel_output *intel_output; | 1782 | struct intel_output *intel_output; |
1787 | struct intel_sdvo_priv *sdvo_priv; | 1783 | struct intel_sdvo_priv *sdvo_priv; |
1788 | struct intel_i2c_chan *i2cbus = NULL; | 1784 | |
1789 | struct intel_i2c_chan *ddcbus = NULL; | ||
1790 | int connector_type; | 1785 | int connector_type; |
1791 | u8 ch[0x40]; | 1786 | u8 ch[0x40]; |
1792 | int i; | 1787 | int i; |
1793 | int encoder_type, output_id; | 1788 | int encoder_type; |
1794 | u8 slave_addr; | ||
1795 | 1789 | ||
1796 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); | 1790 | intel_output = kcalloc(sizeof(struct intel_output)+sizeof(struct intel_sdvo_priv), 1, GFP_KERNEL); |
1797 | if (!intel_output) { | 1791 | if (!intel_output) { |
@@ -1799,29 +1793,24 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1799 | } | 1793 | } |
1800 | 1794 | ||
1801 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); | 1795 | sdvo_priv = (struct intel_sdvo_priv *)(intel_output + 1); |
1796 | sdvo_priv->output_device = output_device; | ||
1797 | |||
1798 | intel_output->dev_priv = sdvo_priv; | ||
1802 | intel_output->type = INTEL_OUTPUT_SDVO; | 1799 | intel_output->type = INTEL_OUTPUT_SDVO; |
1803 | 1800 | ||
1804 | /* setup the DDC bus. */ | 1801 | /* setup the DDC bus. */ |
1805 | if (output_device == SDVOB) | 1802 | if (output_device == SDVOB) |
1806 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); | 1803 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOB"); |
1807 | else | 1804 | else |
1808 | i2cbus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); | 1805 | intel_output->i2c_bus = intel_i2c_create(dev, GPIOE, "SDVOCTRL_E for SDVOC"); |
1809 | 1806 | ||
1810 | if (!i2cbus) | 1807 | if (!intel_output->i2c_bus) |
1811 | goto err_inteloutput; | 1808 | goto err_inteloutput; |
1812 | 1809 | ||
1813 | slave_addr = intel_sdvo_get_slave_addr(dev, output_device); | 1810 | sdvo_priv->slave_addr = intel_sdvo_get_slave_addr(dev, output_device); |
1814 | sdvo_priv->i2c_bus = i2cbus; | ||
1815 | 1811 | ||
1816 | if (output_device == SDVOB) { | 1812 | /* Save the bit-banging i2c functionality for use by the DDC wrapper */ |
1817 | output_id = 1; | 1813 | intel_sdvo_i2c_bit_algo.functionality = intel_output->i2c_bus->algo->functionality; |
1818 | } else { | ||
1819 | output_id = 2; | ||
1820 | } | ||
1821 | sdvo_priv->i2c_bus->slave_addr = slave_addr >> 1; | ||
1822 | sdvo_priv->output_device = output_device; | ||
1823 | intel_output->i2c_bus = i2cbus; | ||
1824 | intel_output->dev_priv = sdvo_priv; | ||
1825 | 1814 | ||
1826 | /* Read the regs to test if we can talk to the device */ | 1815 | /* Read the regs to test if we can talk to the device */ |
1827 | for (i = 0; i < 0x40; i++) { | 1816 | for (i = 0; i < 0x40; i++) { |
@@ -1835,17 +1824,15 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1835 | 1824 | ||
1836 | /* setup the DDC bus. */ | 1825 | /* setup the DDC bus. */ |
1837 | if (output_device == SDVOB) | 1826 | if (output_device == SDVOB) |
1838 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); | 1827 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOB DDC BUS"); |
1839 | else | 1828 | else |
1840 | ddcbus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); | 1829 | intel_output->ddc_bus = intel_i2c_create(dev, GPIOE, "SDVOC DDC BUS"); |
1841 | 1830 | ||
1842 | if (ddcbus == NULL) | 1831 | if (intel_output->ddc_bus == NULL) |
1843 | goto err_i2c; | 1832 | goto err_i2c; |
1844 | 1833 | ||
1845 | intel_sdvo_i2c_bit_algo.functionality = | 1834 | /* Wrap with our custom algo which switches to DDC mode */ |
1846 | intel_output->i2c_bus->adapter.algo->functionality; | 1835 | intel_output->ddc_bus->algo = &intel_sdvo_i2c_bit_algo; |
1847 | ddcbus->adapter.algo = &intel_sdvo_i2c_bit_algo; | ||
1848 | intel_output->ddc_bus = ddcbus; | ||
1849 | 1836 | ||
1850 | /* In defaut case sdvo lvds is false */ | 1837 | /* In defaut case sdvo lvds is false */ |
1851 | sdvo_priv->is_lvds = false; | 1838 | sdvo_priv->is_lvds = false; |
@@ -1965,9 +1952,10 @@ bool intel_sdvo_init(struct drm_device *dev, int output_device) | |||
1965 | return true; | 1952 | return true; |
1966 | 1953 | ||
1967 | err_i2c: | 1954 | err_i2c: |
1968 | if (ddcbus != NULL) | 1955 | if (intel_output->ddc_bus != NULL) |
1969 | intel_i2c_destroy(intel_output->ddc_bus); | 1956 | intel_i2c_destroy(intel_output->ddc_bus); |
1970 | intel_i2c_destroy(intel_output->i2c_bus); | 1957 | if (intel_output->i2c_bus != NULL) |
1958 | intel_i2c_destroy(intel_output->i2c_bus); | ||
1971 | err_inteloutput: | 1959 | err_inteloutput: |
1972 | kfree(intel_output); | 1960 | kfree(intel_output); |
1973 | 1961 | ||