diff options
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_i2c.c')
-rw-r--r-- | drivers/gpu/drm/radeon/radeon_i2c.c | 899 |
1 files changed, 856 insertions, 43 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index dd438d32e5c0..5def6f5dff38 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include "drmP.h" | 26 | #include "drmP.h" |
27 | #include "radeon_drm.h" | 27 | #include "radeon_drm.h" |
28 | #include "radeon.h" | 28 | #include "radeon.h" |
29 | #include "atom.h" | ||
29 | 30 | ||
30 | /** | 31 | /** |
31 | * radeon_ddc_probe | 32 | * radeon_ddc_probe |
@@ -58,36 +59,57 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector) | |||
58 | return false; | 59 | return false; |
59 | } | 60 | } |
60 | 61 | ||
62 | /* bit banging i2c */ | ||
61 | 63 | ||
62 | void radeon_i2c_do_lock(struct radeon_connector *radeon_connector, int lock_state) | 64 | static void radeon_i2c_do_lock(struct radeon_i2c_chan *i2c, int lock_state) |
63 | { | 65 | { |
64 | struct radeon_device *rdev = radeon_connector->base.dev->dev_private; | 66 | struct radeon_device *rdev = i2c->dev->dev_private; |
67 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | ||
65 | uint32_t temp; | 68 | uint32_t temp; |
66 | struct radeon_i2c_bus_rec *rec = &radeon_connector->ddc_bus->rec; | ||
67 | 69 | ||
68 | /* RV410 appears to have a bug where the hw i2c in reset | 70 | /* RV410 appears to have a bug where the hw i2c in reset |
69 | * holds the i2c port in a bad state - switch hw i2c away before | 71 | * holds the i2c port in a bad state - switch hw i2c away before |
70 | * doing DDC - do this for all r200s/r300s/r400s for safety sake | 72 | * doing DDC - do this for all r200s/r300s/r400s for safety sake |
71 | */ | 73 | */ |
72 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { | 74 | if (rec->hw_capable) { |
73 | if (rec->a_clk_reg == RADEON_GPIO_MONID) { | 75 | if ((rdev->family >= CHIP_R200) && !ASIC_IS_AVIVO(rdev)) { |
74 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 76 | u32 reg; |
75 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); | 77 | |
76 | } else { | 78 | if (rdev->family >= CHIP_RV350) |
77 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | 79 | reg = RADEON_GPIO_MONID; |
78 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | 80 | else if ((rdev->family == CHIP_R300) || |
81 | (rdev->family == CHIP_R350)) | ||
82 | reg = RADEON_GPIO_DVI_DDC; | ||
83 | else | ||
84 | reg = RADEON_GPIO_CRT2_DDC; | ||
85 | |||
86 | mutex_lock(&rdev->dc_hw_i2c_mutex); | ||
87 | if (rec->a_clk_reg == reg) { | ||
88 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | ||
89 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1))); | ||
90 | } else { | ||
91 | WREG32(RADEON_DVI_I2C_CNTL_0, (RADEON_I2C_SOFT_RST | | ||
92 | R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3))); | ||
93 | } | ||
94 | mutex_unlock(&rdev->dc_hw_i2c_mutex); | ||
79 | } | 95 | } |
80 | } | 96 | } |
81 | if (lock_state) { | ||
82 | temp = RREG32(rec->a_clk_reg); | ||
83 | temp &= ~(rec->a_clk_mask); | ||
84 | WREG32(rec->a_clk_reg, temp); | ||
85 | 97 | ||
86 | temp = RREG32(rec->a_data_reg); | 98 | /* clear the output pin values */ |
87 | temp &= ~(rec->a_data_mask); | 99 | temp = RREG32(rec->a_clk_reg) & ~rec->a_clk_mask; |
88 | WREG32(rec->a_data_reg, temp); | 100 | WREG32(rec->a_clk_reg, temp); |
89 | } | 101 | |
102 | temp = RREG32(rec->a_data_reg) & ~rec->a_data_mask; | ||
103 | WREG32(rec->a_data_reg, temp); | ||
104 | |||
105 | /* set the pins to input */ | ||
106 | temp = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; | ||
107 | WREG32(rec->en_clk_reg, temp); | ||
90 | 108 | ||
109 | temp = RREG32(rec->en_data_reg) & ~rec->en_data_mask; | ||
110 | WREG32(rec->en_data_reg, temp); | ||
111 | |||
112 | /* mask the gpio pins for software use */ | ||
91 | temp = RREG32(rec->mask_clk_reg); | 113 | temp = RREG32(rec->mask_clk_reg); |
92 | if (lock_state) | 114 | if (lock_state) |
93 | temp |= rec->mask_clk_mask; | 115 | temp |= rec->mask_clk_mask; |
@@ -112,8 +134,9 @@ static int get_clock(void *i2c_priv) | |||
112 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 134 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
113 | uint32_t val; | 135 | uint32_t val; |
114 | 136 | ||
115 | val = RREG32(rec->get_clk_reg); | 137 | /* read the value off the pin */ |
116 | val &= rec->get_clk_mask; | 138 | val = RREG32(rec->y_clk_reg); |
139 | val &= rec->y_clk_mask; | ||
117 | 140 | ||
118 | return (val != 0); | 141 | return (val != 0); |
119 | } | 142 | } |
@@ -126,8 +149,10 @@ static int get_data(void *i2c_priv) | |||
126 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 149 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
127 | uint32_t val; | 150 | uint32_t val; |
128 | 151 | ||
129 | val = RREG32(rec->get_data_reg); | 152 | /* read the value off the pin */ |
130 | val &= rec->get_data_mask; | 153 | val = RREG32(rec->y_data_reg); |
154 | val &= rec->y_data_mask; | ||
155 | |||
131 | return (val != 0); | 156 | return (val != 0); |
132 | } | 157 | } |
133 | 158 | ||
@@ -138,9 +163,10 @@ static void set_clock(void *i2c_priv, int clock) | |||
138 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 163 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
139 | uint32_t val; | 164 | uint32_t val; |
140 | 165 | ||
141 | val = RREG32(rec->put_clk_reg) & (uint32_t)~(rec->put_clk_mask); | 166 | /* set pin direction */ |
142 | val |= clock ? 0 : rec->put_clk_mask; | 167 | val = RREG32(rec->en_clk_reg) & ~rec->en_clk_mask; |
143 | WREG32(rec->put_clk_reg, val); | 168 | val |= clock ? 0 : rec->en_clk_mask; |
169 | WREG32(rec->en_clk_reg, val); | ||
144 | } | 170 | } |
145 | 171 | ||
146 | static void set_data(void *i2c_priv, int data) | 172 | static void set_data(void *i2c_priv, int data) |
@@ -150,15 +176,698 @@ static void set_data(void *i2c_priv, int data) | |||
150 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | 176 | struct radeon_i2c_bus_rec *rec = &i2c->rec; |
151 | uint32_t val; | 177 | uint32_t val; |
152 | 178 | ||
153 | val = RREG32(rec->put_data_reg) & (uint32_t)~(rec->put_data_mask); | 179 | /* set pin direction */ |
154 | val |= data ? 0 : rec->put_data_mask; | 180 | val = RREG32(rec->en_data_reg) & ~rec->en_data_mask; |
155 | WREG32(rec->put_data_reg, val); | 181 | val |= data ? 0 : rec->en_data_mask; |
182 | WREG32(rec->en_data_reg, val); | ||
183 | } | ||
184 | |||
185 | static int pre_xfer(struct i2c_adapter *i2c_adap) | ||
186 | { | ||
187 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
188 | |||
189 | radeon_i2c_do_lock(i2c, 1); | ||
190 | |||
191 | return 0; | ||
192 | } | ||
193 | |||
194 | static void post_xfer(struct i2c_adapter *i2c_adap) | ||
195 | { | ||
196 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
197 | |||
198 | radeon_i2c_do_lock(i2c, 0); | ||
199 | } | ||
200 | |||
201 | /* hw i2c */ | ||
202 | |||
203 | static u32 radeon_get_i2c_prescale(struct radeon_device *rdev) | ||
204 | { | ||
205 | u32 sclk = radeon_get_engine_clock(rdev); | ||
206 | u32 prescale = 0; | ||
207 | u32 nm; | ||
208 | u8 n, m, loop; | ||
209 | int i2c_clock; | ||
210 | |||
211 | switch (rdev->family) { | ||
212 | case CHIP_R100: | ||
213 | case CHIP_RV100: | ||
214 | case CHIP_RS100: | ||
215 | case CHIP_RV200: | ||
216 | case CHIP_RS200: | ||
217 | case CHIP_R200: | ||
218 | case CHIP_RV250: | ||
219 | case CHIP_RS300: | ||
220 | case CHIP_RV280: | ||
221 | case CHIP_R300: | ||
222 | case CHIP_R350: | ||
223 | case CHIP_RV350: | ||
224 | i2c_clock = 60; | ||
225 | nm = (sclk * 10) / (i2c_clock * 4); | ||
226 | for (loop = 1; loop < 255; loop++) { | ||
227 | if ((nm / loop) < loop) | ||
228 | break; | ||
229 | } | ||
230 | n = loop - 1; | ||
231 | m = loop - 2; | ||
232 | prescale = m | (n << 8); | ||
233 | break; | ||
234 | case CHIP_RV380: | ||
235 | case CHIP_RS400: | ||
236 | case CHIP_RS480: | ||
237 | case CHIP_R420: | ||
238 | case CHIP_R423: | ||
239 | case CHIP_RV410: | ||
240 | prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; | ||
241 | break; | ||
242 | case CHIP_RS600: | ||
243 | case CHIP_RS690: | ||
244 | case CHIP_RS740: | ||
245 | /* todo */ | ||
246 | break; | ||
247 | case CHIP_RV515: | ||
248 | case CHIP_R520: | ||
249 | case CHIP_RV530: | ||
250 | case CHIP_RV560: | ||
251 | case CHIP_RV570: | ||
252 | case CHIP_R580: | ||
253 | i2c_clock = 50; | ||
254 | if (rdev->family == CHIP_R520) | ||
255 | prescale = (127 << 8) + ((sclk * 10) / (4 * 127 * i2c_clock)); | ||
256 | else | ||
257 | prescale = (((sclk * 10)/(4 * 128 * 100) + 1) << 8) + 128; | ||
258 | break; | ||
259 | case CHIP_R600: | ||
260 | case CHIP_RV610: | ||
261 | case CHIP_RV630: | ||
262 | case CHIP_RV670: | ||
263 | /* todo */ | ||
264 | break; | ||
265 | case CHIP_RV620: | ||
266 | case CHIP_RV635: | ||
267 | case CHIP_RS780: | ||
268 | case CHIP_RS880: | ||
269 | case CHIP_RV770: | ||
270 | case CHIP_RV730: | ||
271 | case CHIP_RV710: | ||
272 | case CHIP_RV740: | ||
273 | /* todo */ | ||
274 | break; | ||
275 | case CHIP_CEDAR: | ||
276 | case CHIP_REDWOOD: | ||
277 | case CHIP_JUNIPER: | ||
278 | case CHIP_CYPRESS: | ||
279 | case CHIP_HEMLOCK: | ||
280 | /* todo */ | ||
281 | break; | ||
282 | default: | ||
283 | DRM_ERROR("i2c: unhandled radeon chip\n"); | ||
284 | break; | ||
285 | } | ||
286 | return prescale; | ||
287 | } | ||
288 | |||
289 | |||
290 | /* hw i2c engine for r1xx-4xx hardware | ||
291 | * hw can buffer up to 15 bytes | ||
292 | */ | ||
293 | static int r100_hw_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
294 | struct i2c_msg *msgs, int num) | ||
295 | { | ||
296 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
297 | struct radeon_device *rdev = i2c->dev->dev_private; | ||
298 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | ||
299 | struct i2c_msg *p; | ||
300 | int i, j, k, ret = num; | ||
301 | u32 prescale; | ||
302 | u32 i2c_cntl_0, i2c_cntl_1, i2c_data; | ||
303 | u32 tmp, reg; | ||
304 | |||
305 | mutex_lock(&rdev->dc_hw_i2c_mutex); | ||
306 | /* take the pm lock since we need a constant sclk */ | ||
307 | mutex_lock(&rdev->pm.mutex); | ||
308 | |||
309 | prescale = radeon_get_i2c_prescale(rdev); | ||
310 | |||
311 | reg = ((prescale << RADEON_I2C_PRESCALE_SHIFT) | | ||
312 | RADEON_I2C_DRIVE_EN | | ||
313 | RADEON_I2C_START | | ||
314 | RADEON_I2C_STOP | | ||
315 | RADEON_I2C_GO); | ||
316 | |||
317 | if (rdev->is_atom_bios) { | ||
318 | tmp = RREG32(RADEON_BIOS_6_SCRATCH); | ||
319 | WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); | ||
320 | } | ||
321 | |||
322 | if (rec->mm_i2c) { | ||
323 | i2c_cntl_0 = RADEON_I2C_CNTL_0; | ||
324 | i2c_cntl_1 = RADEON_I2C_CNTL_1; | ||
325 | i2c_data = RADEON_I2C_DATA; | ||
326 | } else { | ||
327 | i2c_cntl_0 = RADEON_DVI_I2C_CNTL_0; | ||
328 | i2c_cntl_1 = RADEON_DVI_I2C_CNTL_1; | ||
329 | i2c_data = RADEON_DVI_I2C_DATA; | ||
330 | |||
331 | switch (rdev->family) { | ||
332 | case CHIP_R100: | ||
333 | case CHIP_RV100: | ||
334 | case CHIP_RS100: | ||
335 | case CHIP_RV200: | ||
336 | case CHIP_RS200: | ||
337 | case CHIP_RS300: | ||
338 | switch (rec->mask_clk_reg) { | ||
339 | case RADEON_GPIO_DVI_DDC: | ||
340 | /* no gpio select bit */ | ||
341 | break; | ||
342 | default: | ||
343 | DRM_ERROR("gpio not supported with hw i2c\n"); | ||
344 | ret = -EINVAL; | ||
345 | goto done; | ||
346 | } | ||
347 | break; | ||
348 | case CHIP_R200: | ||
349 | /* only bit 4 on r200 */ | ||
350 | switch (rec->mask_clk_reg) { | ||
351 | case RADEON_GPIO_DVI_DDC: | ||
352 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); | ||
353 | break; | ||
354 | case RADEON_GPIO_MONID: | ||
355 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); | ||
356 | break; | ||
357 | default: | ||
358 | DRM_ERROR("gpio not supported with hw i2c\n"); | ||
359 | ret = -EINVAL; | ||
360 | goto done; | ||
361 | } | ||
362 | break; | ||
363 | case CHIP_RV250: | ||
364 | case CHIP_RV280: | ||
365 | /* bits 3 and 4 */ | ||
366 | switch (rec->mask_clk_reg) { | ||
367 | case RADEON_GPIO_DVI_DDC: | ||
368 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); | ||
369 | break; | ||
370 | case RADEON_GPIO_VGA_DDC: | ||
371 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); | ||
372 | break; | ||
373 | case RADEON_GPIO_CRT2_DDC: | ||
374 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); | ||
375 | break; | ||
376 | default: | ||
377 | DRM_ERROR("gpio not supported with hw i2c\n"); | ||
378 | ret = -EINVAL; | ||
379 | goto done; | ||
380 | } | ||
381 | break; | ||
382 | case CHIP_R300: | ||
383 | case CHIP_R350: | ||
384 | /* only bit 4 on r300/r350 */ | ||
385 | switch (rec->mask_clk_reg) { | ||
386 | case RADEON_GPIO_VGA_DDC: | ||
387 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); | ||
388 | break; | ||
389 | case RADEON_GPIO_DVI_DDC: | ||
390 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); | ||
391 | break; | ||
392 | default: | ||
393 | DRM_ERROR("gpio not supported with hw i2c\n"); | ||
394 | ret = -EINVAL; | ||
395 | goto done; | ||
396 | } | ||
397 | break; | ||
398 | case CHIP_RV350: | ||
399 | case CHIP_RV380: | ||
400 | case CHIP_R420: | ||
401 | case CHIP_R423: | ||
402 | case CHIP_RV410: | ||
403 | case CHIP_RS400: | ||
404 | case CHIP_RS480: | ||
405 | /* bits 3 and 4 */ | ||
406 | switch (rec->mask_clk_reg) { | ||
407 | case RADEON_GPIO_VGA_DDC: | ||
408 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC1); | ||
409 | break; | ||
410 | case RADEON_GPIO_DVI_DDC: | ||
411 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC2); | ||
412 | break; | ||
413 | case RADEON_GPIO_MONID: | ||
414 | reg |= R200_DVI_I2C_PIN_SEL(R200_SEL_DDC3); | ||
415 | break; | ||
416 | default: | ||
417 | DRM_ERROR("gpio not supported with hw i2c\n"); | ||
418 | ret = -EINVAL; | ||
419 | goto done; | ||
420 | } | ||
421 | break; | ||
422 | default: | ||
423 | DRM_ERROR("unsupported asic\n"); | ||
424 | ret = -EINVAL; | ||
425 | goto done; | ||
426 | break; | ||
427 | } | ||
428 | } | ||
429 | |||
430 | /* check for bus probe */ | ||
431 | p = &msgs[0]; | ||
432 | if ((num == 1) && (p->len == 0)) { | ||
433 | WREG32(i2c_cntl_0, (RADEON_I2C_DONE | | ||
434 | RADEON_I2C_NACK | | ||
435 | RADEON_I2C_HALT | | ||
436 | RADEON_I2C_SOFT_RST)); | ||
437 | WREG32(i2c_data, (p->addr << 1) & 0xff); | ||
438 | WREG32(i2c_data, 0); | ||
439 | WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | | ||
440 | (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | | ||
441 | RADEON_I2C_EN | | ||
442 | (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); | ||
443 | WREG32(i2c_cntl_0, reg); | ||
444 | for (k = 0; k < 32; k++) { | ||
445 | udelay(10); | ||
446 | tmp = RREG32(i2c_cntl_0); | ||
447 | if (tmp & RADEON_I2C_GO) | ||
448 | continue; | ||
449 | tmp = RREG32(i2c_cntl_0); | ||
450 | if (tmp & RADEON_I2C_DONE) | ||
451 | break; | ||
452 | else { | ||
453 | DRM_DEBUG("i2c write error 0x%08x\n", tmp); | ||
454 | WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); | ||
455 | ret = -EIO; | ||
456 | goto done; | ||
457 | } | ||
458 | } | ||
459 | goto done; | ||
460 | } | ||
461 | |||
462 | for (i = 0; i < num; i++) { | ||
463 | p = &msgs[i]; | ||
464 | for (j = 0; j < p->len; j++) { | ||
465 | if (p->flags & I2C_M_RD) { | ||
466 | WREG32(i2c_cntl_0, (RADEON_I2C_DONE | | ||
467 | RADEON_I2C_NACK | | ||
468 | RADEON_I2C_HALT | | ||
469 | RADEON_I2C_SOFT_RST)); | ||
470 | WREG32(i2c_data, ((p->addr << 1) & 0xff) | 0x1); | ||
471 | WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | | ||
472 | (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | | ||
473 | RADEON_I2C_EN | | ||
474 | (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); | ||
475 | WREG32(i2c_cntl_0, reg | RADEON_I2C_RECEIVE); | ||
476 | for (k = 0; k < 32; k++) { | ||
477 | udelay(10); | ||
478 | tmp = RREG32(i2c_cntl_0); | ||
479 | if (tmp & RADEON_I2C_GO) | ||
480 | continue; | ||
481 | tmp = RREG32(i2c_cntl_0); | ||
482 | if (tmp & RADEON_I2C_DONE) | ||
483 | break; | ||
484 | else { | ||
485 | DRM_DEBUG("i2c read error 0x%08x\n", tmp); | ||
486 | WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); | ||
487 | ret = -EIO; | ||
488 | goto done; | ||
489 | } | ||
490 | } | ||
491 | p->buf[j] = RREG32(i2c_data) & 0xff; | ||
492 | } else { | ||
493 | WREG32(i2c_cntl_0, (RADEON_I2C_DONE | | ||
494 | RADEON_I2C_NACK | | ||
495 | RADEON_I2C_HALT | | ||
496 | RADEON_I2C_SOFT_RST)); | ||
497 | WREG32(i2c_data, (p->addr << 1) & 0xff); | ||
498 | WREG32(i2c_data, p->buf[j]); | ||
499 | WREG32(i2c_cntl_1, ((1 << RADEON_I2C_DATA_COUNT_SHIFT) | | ||
500 | (1 << RADEON_I2C_ADDR_COUNT_SHIFT) | | ||
501 | RADEON_I2C_EN | | ||
502 | (48 << RADEON_I2C_TIME_LIMIT_SHIFT))); | ||
503 | WREG32(i2c_cntl_0, reg); | ||
504 | for (k = 0; k < 32; k++) { | ||
505 | udelay(10); | ||
506 | tmp = RREG32(i2c_cntl_0); | ||
507 | if (tmp & RADEON_I2C_GO) | ||
508 | continue; | ||
509 | tmp = RREG32(i2c_cntl_0); | ||
510 | if (tmp & RADEON_I2C_DONE) | ||
511 | break; | ||
512 | else { | ||
513 | DRM_DEBUG("i2c write error 0x%08x\n", tmp); | ||
514 | WREG32(i2c_cntl_0, tmp | RADEON_I2C_ABORT); | ||
515 | ret = -EIO; | ||
516 | goto done; | ||
517 | } | ||
518 | } | ||
519 | } | ||
520 | } | ||
521 | } | ||
522 | |||
523 | done: | ||
524 | WREG32(i2c_cntl_0, 0); | ||
525 | WREG32(i2c_cntl_1, 0); | ||
526 | WREG32(i2c_cntl_0, (RADEON_I2C_DONE | | ||
527 | RADEON_I2C_NACK | | ||
528 | RADEON_I2C_HALT | | ||
529 | RADEON_I2C_SOFT_RST)); | ||
530 | |||
531 | if (rdev->is_atom_bios) { | ||
532 | tmp = RREG32(RADEON_BIOS_6_SCRATCH); | ||
533 | tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; | ||
534 | WREG32(RADEON_BIOS_6_SCRATCH, tmp); | ||
535 | } | ||
536 | |||
537 | mutex_unlock(&rdev->pm.mutex); | ||
538 | mutex_unlock(&rdev->dc_hw_i2c_mutex); | ||
539 | |||
540 | return ret; | ||
541 | } | ||
542 | |||
543 | /* hw i2c engine for r5xx hardware | ||
544 | * hw can buffer up to 15 bytes | ||
545 | */ | ||
546 | static int r500_hw_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
547 | struct i2c_msg *msgs, int num) | ||
548 | { | ||
549 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
550 | struct radeon_device *rdev = i2c->dev->dev_private; | ||
551 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | ||
552 | struct i2c_msg *p; | ||
553 | int i, j, remaining, current_count, buffer_offset, ret = num; | ||
554 | u32 prescale; | ||
555 | u32 tmp, reg; | ||
556 | u32 saved1, saved2; | ||
557 | |||
558 | mutex_lock(&rdev->dc_hw_i2c_mutex); | ||
559 | /* take the pm lock since we need a constant sclk */ | ||
560 | mutex_lock(&rdev->pm.mutex); | ||
561 | |||
562 | prescale = radeon_get_i2c_prescale(rdev); | ||
563 | |||
564 | /* clear gpio mask bits */ | ||
565 | tmp = RREG32(rec->mask_clk_reg); | ||
566 | tmp &= ~rec->mask_clk_mask; | ||
567 | WREG32(rec->mask_clk_reg, tmp); | ||
568 | tmp = RREG32(rec->mask_clk_reg); | ||
569 | |||
570 | tmp = RREG32(rec->mask_data_reg); | ||
571 | tmp &= ~rec->mask_data_mask; | ||
572 | WREG32(rec->mask_data_reg, tmp); | ||
573 | tmp = RREG32(rec->mask_data_reg); | ||
574 | |||
575 | /* clear pin values */ | ||
576 | tmp = RREG32(rec->a_clk_reg); | ||
577 | tmp &= ~rec->a_clk_mask; | ||
578 | WREG32(rec->a_clk_reg, tmp); | ||
579 | tmp = RREG32(rec->a_clk_reg); | ||
580 | |||
581 | tmp = RREG32(rec->a_data_reg); | ||
582 | tmp &= ~rec->a_data_mask; | ||
583 | WREG32(rec->a_data_reg, tmp); | ||
584 | tmp = RREG32(rec->a_data_reg); | ||
585 | |||
586 | /* set the pins to input */ | ||
587 | tmp = RREG32(rec->en_clk_reg); | ||
588 | tmp &= ~rec->en_clk_mask; | ||
589 | WREG32(rec->en_clk_reg, tmp); | ||
590 | tmp = RREG32(rec->en_clk_reg); | ||
591 | |||
592 | tmp = RREG32(rec->en_data_reg); | ||
593 | tmp &= ~rec->en_data_mask; | ||
594 | WREG32(rec->en_data_reg, tmp); | ||
595 | tmp = RREG32(rec->en_data_reg); | ||
596 | |||
597 | /* */ | ||
598 | tmp = RREG32(RADEON_BIOS_6_SCRATCH); | ||
599 | WREG32(RADEON_BIOS_6_SCRATCH, tmp | ATOM_S6_HW_I2C_BUSY_STATE); | ||
600 | saved1 = RREG32(AVIVO_DC_I2C_CONTROL1); | ||
601 | saved2 = RREG32(0x494); | ||
602 | WREG32(0x494, saved2 | 0x1); | ||
603 | |||
604 | WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_WANTS_TO_USE_I2C); | ||
605 | for (i = 0; i < 50; i++) { | ||
606 | udelay(1); | ||
607 | if (RREG32(AVIVO_DC_I2C_ARBITRATION) & AVIVO_DC_I2C_SW_CAN_USE_I2C) | ||
608 | break; | ||
609 | } | ||
610 | if (i == 50) { | ||
611 | DRM_ERROR("failed to get i2c bus\n"); | ||
612 | ret = -EBUSY; | ||
613 | goto done; | ||
614 | } | ||
615 | |||
616 | reg = AVIVO_DC_I2C_START | AVIVO_DC_I2C_STOP | AVIVO_DC_I2C_EN; | ||
617 | switch (rec->mask_clk_reg) { | ||
618 | case AVIVO_DC_GPIO_DDC1_MASK: | ||
619 | reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC1); | ||
620 | break; | ||
621 | case AVIVO_DC_GPIO_DDC2_MASK: | ||
622 | reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC2); | ||
623 | break; | ||
624 | case AVIVO_DC_GPIO_DDC3_MASK: | ||
625 | reg |= AVIVO_DC_I2C_PIN_SELECT(AVIVO_SEL_DDC3); | ||
626 | break; | ||
627 | default: | ||
628 | DRM_ERROR("gpio not supported with hw i2c\n"); | ||
629 | ret = -EINVAL; | ||
630 | goto done; | ||
631 | } | ||
632 | |||
633 | /* check for bus probe */ | ||
634 | p = &msgs[0]; | ||
635 | if ((num == 1) && (p->len == 0)) { | ||
636 | WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | | ||
637 | AVIVO_DC_I2C_NACK | | ||
638 | AVIVO_DC_I2C_HALT)); | ||
639 | WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); | ||
640 | udelay(1); | ||
641 | WREG32(AVIVO_DC_I2C_RESET, 0); | ||
642 | |||
643 | WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff); | ||
644 | WREG32(AVIVO_DC_I2C_DATA, 0); | ||
645 | |||
646 | WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); | ||
647 | WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | | ||
648 | AVIVO_DC_I2C_DATA_COUNT(1) | | ||
649 | (prescale << 16))); | ||
650 | WREG32(AVIVO_DC_I2C_CONTROL1, reg); | ||
651 | WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); | ||
652 | for (j = 0; j < 200; j++) { | ||
653 | udelay(50); | ||
654 | tmp = RREG32(AVIVO_DC_I2C_STATUS1); | ||
655 | if (tmp & AVIVO_DC_I2C_GO) | ||
656 | continue; | ||
657 | tmp = RREG32(AVIVO_DC_I2C_STATUS1); | ||
658 | if (tmp & AVIVO_DC_I2C_DONE) | ||
659 | break; | ||
660 | else { | ||
661 | DRM_DEBUG("i2c write error 0x%08x\n", tmp); | ||
662 | WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); | ||
663 | ret = -EIO; | ||
664 | goto done; | ||
665 | } | ||
666 | } | ||
667 | goto done; | ||
668 | } | ||
669 | |||
670 | for (i = 0; i < num; i++) { | ||
671 | p = &msgs[i]; | ||
672 | remaining = p->len; | ||
673 | buffer_offset = 0; | ||
674 | if (p->flags & I2C_M_RD) { | ||
675 | while (remaining) { | ||
676 | if (remaining > 15) | ||
677 | current_count = 15; | ||
678 | else | ||
679 | current_count = remaining; | ||
680 | WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | | ||
681 | AVIVO_DC_I2C_NACK | | ||
682 | AVIVO_DC_I2C_HALT)); | ||
683 | WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); | ||
684 | udelay(1); | ||
685 | WREG32(AVIVO_DC_I2C_RESET, 0); | ||
686 | |||
687 | WREG32(AVIVO_DC_I2C_DATA, ((p->addr << 1) & 0xff) | 0x1); | ||
688 | WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); | ||
689 | WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | | ||
690 | AVIVO_DC_I2C_DATA_COUNT(current_count) | | ||
691 | (prescale << 16))); | ||
692 | WREG32(AVIVO_DC_I2C_CONTROL1, reg | AVIVO_DC_I2C_RECEIVE); | ||
693 | WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); | ||
694 | for (j = 0; j < 200; j++) { | ||
695 | udelay(50); | ||
696 | tmp = RREG32(AVIVO_DC_I2C_STATUS1); | ||
697 | if (tmp & AVIVO_DC_I2C_GO) | ||
698 | continue; | ||
699 | tmp = RREG32(AVIVO_DC_I2C_STATUS1); | ||
700 | if (tmp & AVIVO_DC_I2C_DONE) | ||
701 | break; | ||
702 | else { | ||
703 | DRM_DEBUG("i2c read error 0x%08x\n", tmp); | ||
704 | WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); | ||
705 | ret = -EIO; | ||
706 | goto done; | ||
707 | } | ||
708 | } | ||
709 | for (j = 0; j < current_count; j++) | ||
710 | p->buf[buffer_offset + j] = RREG32(AVIVO_DC_I2C_DATA) & 0xff; | ||
711 | remaining -= current_count; | ||
712 | buffer_offset += current_count; | ||
713 | } | ||
714 | } else { | ||
715 | while (remaining) { | ||
716 | if (remaining > 15) | ||
717 | current_count = 15; | ||
718 | else | ||
719 | current_count = remaining; | ||
720 | WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | | ||
721 | AVIVO_DC_I2C_NACK | | ||
722 | AVIVO_DC_I2C_HALT)); | ||
723 | WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); | ||
724 | udelay(1); | ||
725 | WREG32(AVIVO_DC_I2C_RESET, 0); | ||
726 | |||
727 | WREG32(AVIVO_DC_I2C_DATA, (p->addr << 1) & 0xff); | ||
728 | for (j = 0; j < current_count; j++) | ||
729 | WREG32(AVIVO_DC_I2C_DATA, p->buf[buffer_offset + j]); | ||
730 | |||
731 | WREG32(AVIVO_DC_I2C_CONTROL3, AVIVO_DC_I2C_TIME_LIMIT(48)); | ||
732 | WREG32(AVIVO_DC_I2C_CONTROL2, (AVIVO_DC_I2C_ADDR_COUNT(1) | | ||
733 | AVIVO_DC_I2C_DATA_COUNT(current_count) | | ||
734 | (prescale << 16))); | ||
735 | WREG32(AVIVO_DC_I2C_CONTROL1, reg); | ||
736 | WREG32(AVIVO_DC_I2C_STATUS1, AVIVO_DC_I2C_GO); | ||
737 | for (j = 0; j < 200; j++) { | ||
738 | udelay(50); | ||
739 | tmp = RREG32(AVIVO_DC_I2C_STATUS1); | ||
740 | if (tmp & AVIVO_DC_I2C_GO) | ||
741 | continue; | ||
742 | tmp = RREG32(AVIVO_DC_I2C_STATUS1); | ||
743 | if (tmp & AVIVO_DC_I2C_DONE) | ||
744 | break; | ||
745 | else { | ||
746 | DRM_DEBUG("i2c write error 0x%08x\n", tmp); | ||
747 | WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_ABORT); | ||
748 | ret = -EIO; | ||
749 | goto done; | ||
750 | } | ||
751 | } | ||
752 | remaining -= current_count; | ||
753 | buffer_offset += current_count; | ||
754 | } | ||
755 | } | ||
756 | } | ||
757 | |||
758 | done: | ||
759 | WREG32(AVIVO_DC_I2C_STATUS1, (AVIVO_DC_I2C_DONE | | ||
760 | AVIVO_DC_I2C_NACK | | ||
761 | AVIVO_DC_I2C_HALT)); | ||
762 | WREG32(AVIVO_DC_I2C_RESET, AVIVO_DC_I2C_SOFT_RESET); | ||
763 | udelay(1); | ||
764 | WREG32(AVIVO_DC_I2C_RESET, 0); | ||
765 | |||
766 | WREG32(AVIVO_DC_I2C_ARBITRATION, AVIVO_DC_I2C_SW_DONE_USING_I2C); | ||
767 | WREG32(AVIVO_DC_I2C_CONTROL1, saved1); | ||
768 | WREG32(0x494, saved2); | ||
769 | tmp = RREG32(RADEON_BIOS_6_SCRATCH); | ||
770 | tmp &= ~ATOM_S6_HW_I2C_BUSY_STATE; | ||
771 | WREG32(RADEON_BIOS_6_SCRATCH, tmp); | ||
772 | |||
773 | mutex_unlock(&rdev->pm.mutex); | ||
774 | mutex_unlock(&rdev->dc_hw_i2c_mutex); | ||
775 | |||
776 | return ret; | ||
777 | } | ||
778 | |||
779 | static int radeon_hw_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
780 | struct i2c_msg *msgs, int num) | ||
781 | { | ||
782 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
783 | struct radeon_device *rdev = i2c->dev->dev_private; | ||
784 | struct radeon_i2c_bus_rec *rec = &i2c->rec; | ||
785 | int ret = 0; | ||
786 | |||
787 | switch (rdev->family) { | ||
788 | case CHIP_R100: | ||
789 | case CHIP_RV100: | ||
790 | case CHIP_RS100: | ||
791 | case CHIP_RV200: | ||
792 | case CHIP_RS200: | ||
793 | case CHIP_R200: | ||
794 | case CHIP_RV250: | ||
795 | case CHIP_RS300: | ||
796 | case CHIP_RV280: | ||
797 | case CHIP_R300: | ||
798 | case CHIP_R350: | ||
799 | case CHIP_RV350: | ||
800 | case CHIP_RV380: | ||
801 | case CHIP_R420: | ||
802 | case CHIP_R423: | ||
803 | case CHIP_RV410: | ||
804 | case CHIP_RS400: | ||
805 | case CHIP_RS480: | ||
806 | ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); | ||
807 | break; | ||
808 | case CHIP_RS600: | ||
809 | case CHIP_RS690: | ||
810 | case CHIP_RS740: | ||
811 | /* XXX fill in hw i2c implementation */ | ||
812 | break; | ||
813 | case CHIP_RV515: | ||
814 | case CHIP_R520: | ||
815 | case CHIP_RV530: | ||
816 | case CHIP_RV560: | ||
817 | case CHIP_RV570: | ||
818 | case CHIP_R580: | ||
819 | if (rec->mm_i2c) | ||
820 | ret = r100_hw_i2c_xfer(i2c_adap, msgs, num); | ||
821 | else | ||
822 | ret = r500_hw_i2c_xfer(i2c_adap, msgs, num); | ||
823 | break; | ||
824 | case CHIP_R600: | ||
825 | case CHIP_RV610: | ||
826 | case CHIP_RV630: | ||
827 | case CHIP_RV670: | ||
828 | /* XXX fill in hw i2c implementation */ | ||
829 | break; | ||
830 | case CHIP_RV620: | ||
831 | case CHIP_RV635: | ||
832 | case CHIP_RS780: | ||
833 | case CHIP_RS880: | ||
834 | case CHIP_RV770: | ||
835 | case CHIP_RV730: | ||
836 | case CHIP_RV710: | ||
837 | case CHIP_RV740: | ||
838 | /* XXX fill in hw i2c implementation */ | ||
839 | break; | ||
840 | case CHIP_CEDAR: | ||
841 | case CHIP_REDWOOD: | ||
842 | case CHIP_JUNIPER: | ||
843 | case CHIP_CYPRESS: | ||
844 | case CHIP_HEMLOCK: | ||
845 | /* XXX fill in hw i2c implementation */ | ||
846 | break; | ||
847 | default: | ||
848 | DRM_ERROR("i2c: unhandled radeon chip\n"); | ||
849 | ret = -EIO; | ||
850 | break; | ||
851 | } | ||
852 | |||
853 | return ret; | ||
854 | } | ||
855 | |||
856 | static u32 radeon_hw_i2c_func(struct i2c_adapter *adap) | ||
857 | { | ||
858 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
156 | } | 859 | } |
157 | 860 | ||
861 | static const struct i2c_algorithm radeon_i2c_algo = { | ||
862 | .master_xfer = radeon_hw_i2c_xfer, | ||
863 | .functionality = radeon_hw_i2c_func, | ||
864 | }; | ||
865 | |||
158 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 866 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
159 | struct radeon_i2c_bus_rec *rec, | 867 | struct radeon_i2c_bus_rec *rec, |
160 | const char *name) | 868 | const char *name) |
161 | { | 869 | { |
870 | struct radeon_device *rdev = dev->dev_private; | ||
162 | struct radeon_i2c_chan *i2c; | 871 | struct radeon_i2c_chan *i2c; |
163 | int ret; | 872 | int ret; |
164 | 873 | ||
@@ -166,22 +875,71 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
166 | if (i2c == NULL) | 875 | if (i2c == NULL) |
167 | return NULL; | 876 | return NULL; |
168 | 877 | ||
878 | i2c->rec = *rec; | ||
169 | i2c->adapter.owner = THIS_MODULE; | 879 | i2c->adapter.owner = THIS_MODULE; |
170 | i2c->adapter.algo_data = &i2c->algo; | ||
171 | i2c->dev = dev; | 880 | i2c->dev = dev; |
172 | i2c->algo.setsda = set_data; | ||
173 | i2c->algo.setscl = set_clock; | ||
174 | i2c->algo.getsda = get_data; | ||
175 | i2c->algo.getscl = get_clock; | ||
176 | i2c->algo.udelay = 20; | ||
177 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | ||
178 | * make this, 2 jiffies is a lot more reliable */ | ||
179 | i2c->algo.timeout = 2; | ||
180 | i2c->algo.data = i2c; | ||
181 | i2c->rec = *rec; | ||
182 | i2c_set_adapdata(&i2c->adapter, i2c); | 881 | i2c_set_adapdata(&i2c->adapter, i2c); |
882 | if (rec->mm_i2c || | ||
883 | (rec->hw_capable && | ||
884 | radeon_hw_i2c && | ||
885 | ((rdev->family <= CHIP_RS480) || | ||
886 | ((rdev->family >= CHIP_RV515) && (rdev->family <= CHIP_R580))))) { | ||
887 | /* set the radeon hw i2c adapter */ | ||
888 | sprintf(i2c->adapter.name, "Radeon i2c hw bus %s", name); | ||
889 | i2c->adapter.algo = &radeon_i2c_algo; | ||
890 | ret = i2c_add_adapter(&i2c->adapter); | ||
891 | if (ret) { | ||
892 | DRM_ERROR("Failed to register hw i2c %s\n", name); | ||
893 | goto out_free; | ||
894 | } | ||
895 | } else { | ||
896 | /* set the radeon bit adapter */ | ||
897 | sprintf(i2c->adapter.name, "Radeon i2c bit bus %s", name); | ||
898 | i2c->adapter.algo_data = &i2c->algo.bit; | ||
899 | i2c->algo.bit.pre_xfer = pre_xfer; | ||
900 | i2c->algo.bit.post_xfer = post_xfer; | ||
901 | i2c->algo.bit.setsda = set_data; | ||
902 | i2c->algo.bit.setscl = set_clock; | ||
903 | i2c->algo.bit.getsda = get_data; | ||
904 | i2c->algo.bit.getscl = get_clock; | ||
905 | i2c->algo.bit.udelay = 20; | ||
906 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | ||
907 | * make this, 2 jiffies is a lot more reliable */ | ||
908 | i2c->algo.bit.timeout = 2; | ||
909 | i2c->algo.bit.data = i2c; | ||
910 | ret = i2c_bit_add_bus(&i2c->adapter); | ||
911 | if (ret) { | ||
912 | DRM_ERROR("Failed to register bit i2c %s\n", name); | ||
913 | goto out_free; | ||
914 | } | ||
915 | } | ||
916 | |||
917 | return i2c; | ||
918 | out_free: | ||
919 | kfree(i2c); | ||
920 | return NULL; | ||
921 | |||
922 | } | ||
183 | 923 | ||
184 | ret = i2c_bit_add_bus(&i2c->adapter); | 924 | struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev, |
925 | struct radeon_i2c_bus_rec *rec, | ||
926 | const char *name) | ||
927 | { | ||
928 | struct radeon_i2c_chan *i2c; | ||
929 | int ret; | ||
930 | |||
931 | i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL); | ||
932 | if (i2c == NULL) | ||
933 | return NULL; | ||
934 | |||
935 | i2c->rec = *rec; | ||
936 | i2c->adapter.owner = THIS_MODULE; | ||
937 | i2c->dev = dev; | ||
938 | i2c_set_adapdata(&i2c->adapter, i2c); | ||
939 | i2c->adapter.algo_data = &i2c->algo.dp; | ||
940 | i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch; | ||
941 | i2c->algo.dp.address = 0; | ||
942 | ret = i2c_dp_aux_add_bus(&i2c->adapter); | ||
185 | if (ret) { | 943 | if (ret) { |
186 | DRM_INFO("Failed to register i2c %s\n", name); | 944 | DRM_INFO("Failed to register i2c %s\n", name); |
187 | goto out_free; | 945 | goto out_free; |
@@ -198,7 +956,6 @@ void radeon_i2c_destroy(struct radeon_i2c_chan *i2c) | |||
198 | { | 956 | { |
199 | if (!i2c) | 957 | if (!i2c) |
200 | return; | 958 | return; |
201 | |||
202 | i2c_del_adapter(&i2c->adapter); | 959 | i2c_del_adapter(&i2c->adapter); |
203 | kfree(i2c); | 960 | kfree(i2c); |
204 | } | 961 | } |
@@ -207,3 +964,59 @@ struct drm_encoder *radeon_best_encoder(struct drm_connector *connector) | |||
207 | { | 964 | { |
208 | return NULL; | 965 | return NULL; |
209 | } | 966 | } |
967 | |||
968 | void radeon_i2c_get_byte(struct radeon_i2c_chan *i2c_bus, | ||
969 | u8 slave_addr, | ||
970 | u8 addr, | ||
971 | u8 *val) | ||
972 | { | ||
973 | u8 out_buf[2]; | ||
974 | u8 in_buf[2]; | ||
975 | struct i2c_msg msgs[] = { | ||
976 | { | ||
977 | .addr = slave_addr, | ||
978 | .flags = 0, | ||
979 | .len = 1, | ||
980 | .buf = out_buf, | ||
981 | }, | ||
982 | { | ||
983 | .addr = slave_addr, | ||
984 | .flags = I2C_M_RD, | ||
985 | .len = 1, | ||
986 | .buf = in_buf, | ||
987 | } | ||
988 | }; | ||
989 | |||
990 | out_buf[0] = addr; | ||
991 | out_buf[1] = 0; | ||
992 | |||
993 | if (i2c_transfer(&i2c_bus->adapter, msgs, 2) == 2) { | ||
994 | *val = in_buf[0]; | ||
995 | DRM_DEBUG("val = 0x%02x\n", *val); | ||
996 | } else { | ||
997 | DRM_ERROR("i2c 0x%02x 0x%02x read failed\n", | ||
998 | addr, *val); | ||
999 | } | ||
1000 | } | ||
1001 | |||
1002 | void radeon_i2c_put_byte(struct radeon_i2c_chan *i2c_bus, | ||
1003 | u8 slave_addr, | ||
1004 | u8 addr, | ||
1005 | u8 val) | ||
1006 | { | ||
1007 | uint8_t out_buf[2]; | ||
1008 | struct i2c_msg msg = { | ||
1009 | .addr = slave_addr, | ||
1010 | .flags = 0, | ||
1011 | .len = 2, | ||
1012 | .buf = out_buf, | ||
1013 | }; | ||
1014 | |||
1015 | out_buf[0] = addr; | ||
1016 | out_buf[1] = val; | ||
1017 | |||
1018 | if (i2c_transfer(&i2c_bus->adapter, &msg, 1) != 1) | ||
1019 | DRM_ERROR("i2c 0x%02x 0x%02x write failed\n", | ||
1020 | addr, val); | ||
1021 | } | ||
1022 | |||