aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/Kconfig1
-rw-r--r--drivers/video/aty/radeon_i2c.c106
2 files changed, 4 insertions, 103 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 0e371e060871..a1c8923b0bf5 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1020,6 +1020,7 @@ config FB_RADEON
1020 depends on FB && PCI 1020 depends on FB && PCI
1021 select I2C_ALGOBIT if FB_RADEON_I2C 1021 select I2C_ALGOBIT if FB_RADEON_I2C
1022 select I2C if FB_RADEON_I2C 1022 select I2C if FB_RADEON_I2C
1023 select FB_DDC if FB_RADEON_I2C
1023 select FB_MODE_HELPERS 1024 select FB_MODE_HELPERS
1024 select FB_CFB_FILLRECT 1025 select FB_CFB_FILLRECT
1025 select FB_CFB_COPYAREA 1026 select FB_CFB_COPYAREA
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/aty/radeon_i2c.c
index 9aaca58c074a..676754520099 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/aty/radeon_i2c.c
@@ -16,8 +16,6 @@
16#include "radeonfb.h" 16#include "radeonfb.h"
17#include "../edid.h" 17#include "../edid.h"
18 18
19#define RADEON_DDC 0x50
20
21static void radeon_gpio_setscl(void* data, int state) 19static void radeon_gpio_setscl(void* data, int state)
22{ 20{
23 struct radeon_i2c_chan *chan = data; 21 struct radeon_i2c_chan *chan = data;
@@ -138,108 +136,10 @@ void radeon_delete_i2c_busses(struct radeonfb_info *rinfo)
138 rinfo->i2c[3].rinfo = NULL; 136 rinfo->i2c[3].rinfo = NULL;
139} 137}
140 138
141 139int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn,
142static u8 *radeon_do_probe_i2c_edid(struct radeon_i2c_chan *chan) 140 u8 **out_edid)
143{
144 u8 start = 0x0;
145 struct i2c_msg msgs[] = {
146 {
147 .addr = RADEON_DDC,
148 .len = 1,
149 .buf = &start,
150 }, {
151 .addr = RADEON_DDC,
152 .flags = I2C_M_RD,
153 .len = EDID_LENGTH,
154 },
155 };
156 u8 *buf;
157
158 buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
159 if (!buf) {
160 dev_warn(&chan->rinfo->pdev->dev, "Out of memory!\n");
161 return NULL;
162 }
163 msgs[1].buf = buf;
164
165 if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
166 return buf;
167 dev_dbg(&chan->rinfo->pdev->dev, "Unable to read EDID block.\n");
168 kfree(buf);
169 return NULL;
170}
171
172
173int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, u8 **out_edid)
174{ 141{
175 u32 reg = rinfo->i2c[conn-1].ddc_reg; 142 u8 *edid = fb_ddc_read(&rinfo->i2c[conn-1].adapter);
176 u8 *edid = NULL;
177 int i, j;
178
179 OUTREG(reg, INREG(reg) &
180 ~(VGA_DDC_DATA_OUTPUT | VGA_DDC_CLK_OUTPUT));
181
182 OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
183 (void)INREG(reg);
184
185 for (i = 0; i < 3; i++) {
186 /* For some old monitors we need the
187 * following process to initialize/stop DDC
188 */
189 OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
190 (void)INREG(reg);
191 msleep(13);
192
193 OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
194 (void)INREG(reg);
195 for (j = 0; j < 5; j++) {
196 msleep(10);
197 if (INREG(reg) & VGA_DDC_CLK_INPUT)
198 break;
199 }
200 if (j == 5)
201 continue;
202
203 OUTREG(reg, INREG(reg) | VGA_DDC_DATA_OUT_EN);
204 (void)INREG(reg);
205 msleep(15);
206 OUTREG(reg, INREG(reg) | VGA_DDC_CLK_OUT_EN);
207 (void)INREG(reg);
208 msleep(15);
209 OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
210 (void)INREG(reg);
211 msleep(15);
212
213 /* Do the real work */
214 edid = radeon_do_probe_i2c_edid(&rinfo->i2c[conn-1]);
215
216 OUTREG(reg, INREG(reg) |
217 (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
218 (void)INREG(reg);
219 msleep(15);
220
221 OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN));
222 (void)INREG(reg);
223 for (j = 0; j < 10; j++) {
224 msleep(10);
225 if (INREG(reg) & VGA_DDC_CLK_INPUT)
226 break;
227 }
228
229 OUTREG(reg, INREG(reg) & ~(VGA_DDC_DATA_OUT_EN));
230 (void)INREG(reg);
231 msleep(15);
232 OUTREG(reg, INREG(reg) |
233 (VGA_DDC_DATA_OUT_EN | VGA_DDC_CLK_OUT_EN));
234 (void)INREG(reg);
235 if (edid)
236 break;
237 }
238 /* Release the DDC lines when done or the Apple Cinema HD display
239 * will switch off
240 */
241 OUTREG(reg, INREG(reg) & ~(VGA_DDC_CLK_OUT_EN | VGA_DDC_DATA_OUT_EN));
242 (void)INREG(reg);
243 143
244 if (out_edid) 144 if (out_edid)
245 *out_edid = edid; 145 *out_edid = edid;