diff options
author | Daniel Kurtz <djkurtz@chromium.org> | 2012-03-27 14:36:10 -0400 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-03-28 03:23:37 -0400 |
commit | 924a93edc96b7f7e08a0af7a2f9afe4827bab103 (patch) | |
tree | 929ff22346337429f61291b0e910dc6186298f9f | |
parent | e7e58eb5c0d1d7d1a42fcb2b5a247d28ec08b47e (diff) |
drm/i915/intel_i2c: refactor gmbus_xfer
Split out gmbus_xfer_read/write() helper functions.
Signed-off-by: Daniel Kurtz <djkurtz@chromium.org>
Reviewed-by: Chris Wilson <chris@chris-wilson.co.uk>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 151 |
1 files changed, 92 insertions, 59 deletions
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 0713cc289119..30675ce18056 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -198,6 +198,82 @@ intel_i2c_quirk_xfer(struct intel_gmbus *bus, | |||
198 | } | 198 | } |
199 | 199 | ||
200 | static int | 200 | static int |
201 | gmbus_xfer_read(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | ||
202 | bool last) | ||
203 | { | ||
204 | int reg_offset = dev_priv->gpio_mmio_base; | ||
205 | u16 len = msg->len; | ||
206 | u8 *buf = msg->buf; | ||
207 | |||
208 | I915_WRITE(GMBUS1 + reg_offset, | ||
209 | GMBUS_CYCLE_WAIT | | ||
210 | (last ? GMBUS_CYCLE_STOP : 0) | | ||
211 | (len << GMBUS_BYTE_COUNT_SHIFT) | | ||
212 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | | ||
213 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | ||
214 | POSTING_READ(GMBUS2 + reg_offset); | ||
215 | do { | ||
216 | u32 val, loop = 0; | ||
217 | |||
218 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & | ||
219 | (GMBUS_SATOER | GMBUS_HW_RDY), | ||
220 | 50)) | ||
221 | return -ETIMEDOUT; | ||
222 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
223 | return -ENXIO; | ||
224 | |||
225 | val = I915_READ(GMBUS3 + reg_offset); | ||
226 | do { | ||
227 | *buf++ = val & 0xff; | ||
228 | val >>= 8; | ||
229 | } while (--len && ++loop < 4); | ||
230 | } while (len); | ||
231 | |||
232 | return 0; | ||
233 | } | ||
234 | |||
235 | static int | ||
236 | gmbus_xfer_write(struct drm_i915_private *dev_priv, struct i2c_msg *msg, | ||
237 | bool last) | ||
238 | { | ||
239 | int reg_offset = dev_priv->gpio_mmio_base; | ||
240 | u16 len = msg->len; | ||
241 | u8 *buf = msg->buf; | ||
242 | u32 val, loop; | ||
243 | |||
244 | val = loop = 0; | ||
245 | do { | ||
246 | val |= *buf++ << (8 * loop); | ||
247 | } while (--len && ++loop < 4); | ||
248 | |||
249 | I915_WRITE(GMBUS3 + reg_offset, val); | ||
250 | I915_WRITE(GMBUS1 + reg_offset, | ||
251 | GMBUS_CYCLE_WAIT | | ||
252 | (last ? GMBUS_CYCLE_STOP : 0) | | ||
253 | (msg->len << GMBUS_BYTE_COUNT_SHIFT) | | ||
254 | (msg->addr << GMBUS_SLAVE_ADDR_SHIFT) | | ||
255 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | ||
256 | POSTING_READ(GMBUS2 + reg_offset); | ||
257 | while (len) { | ||
258 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & | ||
259 | (GMBUS_SATOER | GMBUS_HW_RDY), | ||
260 | 50)) | ||
261 | return -ETIMEDOUT; | ||
262 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
263 | return -ENXIO; | ||
264 | |||
265 | val = loop = 0; | ||
266 | do { | ||
267 | val |= *buf++ << (8 * loop); | ||
268 | } while (--len && ++loop < 4); | ||
269 | |||
270 | I915_WRITE(GMBUS3 + reg_offset, val); | ||
271 | POSTING_READ(GMBUS2 + reg_offset); | ||
272 | } | ||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int | ||
201 | gmbus_xfer(struct i2c_adapter *adapter, | 277 | gmbus_xfer(struct i2c_adapter *adapter, |
202 | struct i2c_msg *msgs, | 278 | struct i2c_msg *msgs, |
203 | int num) | 279 | int num) |
@@ -220,65 +296,22 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
220 | I915_WRITE(GMBUS0 + reg_offset, bus->reg0); | 296 | I915_WRITE(GMBUS0 + reg_offset, bus->reg0); |
221 | 297 | ||
222 | for (i = 0; i < num; i++) { | 298 | for (i = 0; i < num; i++) { |
223 | u16 len = msgs[i].len; | 299 | bool last = i + 1 == num; |
224 | u8 *buf = msgs[i].buf; | 300 | |
225 | 301 | if (msgs[i].flags & I2C_M_RD) | |
226 | if (msgs[i].flags & I2C_M_RD) { | 302 | ret = gmbus_xfer_read(dev_priv, &msgs[i], last); |
227 | I915_WRITE(GMBUS1 + reg_offset, | 303 | else |
228 | GMBUS_CYCLE_WAIT | | 304 | ret = gmbus_xfer_write(dev_priv, &msgs[i], last); |
229 | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | | 305 | |
230 | (len << GMBUS_BYTE_COUNT_SHIFT) | | 306 | if (ret == -ETIMEDOUT) |
231 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | 307 | goto timeout; |
232 | GMBUS_SLAVE_READ | GMBUS_SW_RDY); | 308 | if (ret == -ENXIO) |
233 | POSTING_READ(GMBUS2+reg_offset); | 309 | goto clear_err; |
234 | do { | 310 | |
235 | u32 val, loop = 0; | 311 | if (!last && |
236 | 312 | wait_for(I915_READ(GMBUS2 + reg_offset) & | |
237 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | 313 | (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), |
238 | goto timeout; | 314 | 50)) |
239 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
240 | goto clear_err; | ||
241 | |||
242 | val = I915_READ(GMBUS3 + reg_offset); | ||
243 | do { | ||
244 | *buf++ = val & 0xff; | ||
245 | val >>= 8; | ||
246 | } while (--len && ++loop < 4); | ||
247 | } while (len); | ||
248 | } else { | ||
249 | u32 val, loop; | ||
250 | |||
251 | val = loop = 0; | ||
252 | do { | ||
253 | val |= *buf++ << (8 * loop); | ||
254 | } while (--len && ++loop < 4); | ||
255 | |||
256 | I915_WRITE(GMBUS3 + reg_offset, val); | ||
257 | I915_WRITE(GMBUS1 + reg_offset, | ||
258 | GMBUS_CYCLE_WAIT | | ||
259 | (i + 1 == num ? GMBUS_CYCLE_STOP : 0) | | ||
260 | (msgs[i].len << GMBUS_BYTE_COUNT_SHIFT) | | ||
261 | (msgs[i].addr << GMBUS_SLAVE_ADDR_SHIFT) | | ||
262 | GMBUS_SLAVE_WRITE | GMBUS_SW_RDY); | ||
263 | POSTING_READ(GMBUS2+reg_offset); | ||
264 | |||
265 | while (len) { | ||
266 | if (wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_RDY), 50)) | ||
267 | goto timeout; | ||
268 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | ||
269 | goto clear_err; | ||
270 | |||
271 | val = loop = 0; | ||
272 | do { | ||
273 | val |= *buf++ << (8 * loop); | ||
274 | } while (--len && ++loop < 4); | ||
275 | |||
276 | I915_WRITE(GMBUS3 + reg_offset, val); | ||
277 | POSTING_READ(GMBUS2+reg_offset); | ||
278 | } | ||
279 | } | ||
280 | |||
281 | if (i + 1 < num && wait_for(I915_READ(GMBUS2 + reg_offset) & (GMBUS_SATOER | GMBUS_HW_WAIT_PHASE), 50)) | ||
282 | goto timeout; | 315 | goto timeout; |
283 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) | 316 | if (I915_READ(GMBUS2 + reg_offset) & GMBUS_SATOER) |
284 | goto clear_err; | 317 | goto clear_err; |