diff options
-rw-r--r-- | drivers/video/Kconfig | 1 | ||||
-rw-r--r-- | drivers/video/aty/radeon_i2c.c | 106 |
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 | |||
21 | static void radeon_gpio_setscl(void* data, int state) | 19 | static 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 | 139 | int radeon_probe_i2c_connector(struct radeonfb_info *rinfo, int conn, | |
142 | static 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 | |||
173 | int 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; |