diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-02-14 12:58:49 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-02-29 14:53:36 -0500 |
commit | f6f808c8e1c4a3b7e3e0a6cb81541ec615aeb5fd (patch) | |
tree | 1755f20d63cc3066a16263961272fbd3f6b077c5 /drivers/gpu/drm | |
parent | c167a6fc6ed78a300c29181a6caf9ae1b9993289 (diff) |
drm/i915: i2c: unconditionally set up gpio fallback
This way we can simplify the setup and teardown a bit.
Because we don't actually allocate anything anymore for the force_bit
case, we can now convert that into a boolean.
Also and the functionality supported by the bit-banging together with
what gmbus can do, so that this doesn't randomly change any more.
v2: Chris Wilson noticed that I've mixed up && and & ...
v3: Clarify an if block as suggested by Eugeni Dodonov.
Reviewed-by: Eugeni Dodonov <eugeni.dodonov@intel.com>
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r-- | drivers/gpu/drm/i915/i915_drv.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/i915/intel_i2c.c | 51 |
2 files changed, 22 insertions, 32 deletions
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 47b315ca2ca..c0f19f57200 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -301,7 +301,8 @@ struct intel_fbc_work; | |||
301 | 301 | ||
302 | struct intel_gmbus { | 302 | struct intel_gmbus { |
303 | struct i2c_adapter adapter; | 303 | struct i2c_adapter adapter; |
304 | struct i2c_adapter *force_bit; | 304 | bool force_bit; |
305 | bool has_gpio; | ||
305 | u32 reg0; | 306 | u32 reg0; |
306 | u32 gpio_reg; | 307 | u32 gpio_reg; |
307 | struct i2c_algo_bit_data bit_algo; | 308 | struct i2c_algo_bit_data bit_algo; |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 43dde957a32..8fdc9570021 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -140,8 +140,8 @@ static void set_data(void *data, int state_high) | |||
140 | POSTING_READ(bus->gpio_reg); | 140 | POSTING_READ(bus->gpio_reg); |
141 | } | 141 | } |
142 | 142 | ||
143 | static struct i2c_adapter * | 143 | static bool |
144 | intel_gpio_create(struct intel_gmbus *bus, u32 pin) | 144 | intel_gpio_setup(struct intel_gmbus *bus, u32 pin) |
145 | { | 145 | { |
146 | struct drm_i915_private *dev_priv = bus->dev_priv; | 146 | struct drm_i915_private *dev_priv = bus->dev_priv; |
147 | static const int map_pin_to_reg[] = { | 147 | static const int map_pin_to_reg[] = { |
@@ -157,7 +157,7 @@ intel_gpio_create(struct intel_gmbus *bus, u32 pin) | |||
157 | struct i2c_algo_bit_data *algo; | 157 | struct i2c_algo_bit_data *algo; |
158 | 158 | ||
159 | if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin]) | 159 | if (pin >= ARRAY_SIZE(map_pin_to_reg) || !map_pin_to_reg[pin]) |
160 | return NULL; | 160 | return false; |
161 | 161 | ||
162 | algo = &bus->bit_algo; | 162 | algo = &bus->bit_algo; |
163 | 163 | ||
@@ -174,12 +174,11 @@ intel_gpio_create(struct intel_gmbus *bus, u32 pin) | |||
174 | algo->timeout = usecs_to_jiffies(2200); | 174 | algo->timeout = usecs_to_jiffies(2200); |
175 | algo->data = bus; | 175 | algo->data = bus; |
176 | 176 | ||
177 | return &bus->adapter; | 177 | return true; |
178 | } | 178 | } |
179 | 179 | ||
180 | static int | 180 | static int |
181 | intel_i2c_quirk_xfer(struct intel_gmbus *bus, | 181 | intel_i2c_quirk_xfer(struct intel_gmbus *bus, |
182 | struct i2c_adapter *adapter, | ||
183 | struct i2c_msg *msgs, | 182 | struct i2c_msg *msgs, |
184 | int num) | 183 | int num) |
185 | { | 184 | { |
@@ -193,7 +192,7 @@ intel_i2c_quirk_xfer(struct intel_gmbus *bus, | |||
193 | set_clock(bus, 1); | 192 | set_clock(bus, 1); |
194 | udelay(I2C_RISEFALL_TIME); | 193 | udelay(I2C_RISEFALL_TIME); |
195 | 194 | ||
196 | ret = i2c_bit_algo.master_xfer(adapter, msgs, num); | 195 | ret = i2c_bit_algo.master_xfer(&bus->adapter, msgs, num); |
197 | 196 | ||
198 | set_data(bus, 1); | 197 | set_data(bus, 1); |
199 | set_clock(bus, 1); | 198 | set_clock(bus, 1); |
@@ -216,7 +215,7 @@ gmbus_xfer(struct i2c_adapter *adapter, | |||
216 | mutex_lock(&dev_priv->gmbus_mutex); | 215 | mutex_lock(&dev_priv->gmbus_mutex); |
217 | 216 | ||
218 | if (bus->force_bit) { | 217 | if (bus->force_bit) { |
219 | ret = intel_i2c_quirk_xfer(bus, bus->force_bit, msgs, num); | 218 | ret = intel_i2c_quirk_xfer(bus, msgs, num); |
220 | goto out; | 219 | goto out; |
221 | } | 220 | } |
222 | 221 | ||
@@ -316,11 +315,12 @@ timeout: | |||
316 | I915_WRITE(GMBUS0 + reg_offset, 0); | 315 | I915_WRITE(GMBUS0 + reg_offset, 0); |
317 | 316 | ||
318 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ | 317 | /* Hardware may not support GMBUS over these pins? Try GPIO bitbanging instead. */ |
319 | bus->force_bit = intel_gpio_create(bus, bus->reg0 & 0xff); | 318 | if (!bus->has_gpio) { |
320 | if (!bus->force_bit) | 319 | ret = -EIO; |
321 | ret = -ENOMEM; | 320 | } else { |
322 | else | 321 | bus->force_bit = true; |
323 | ret = intel_i2c_quirk_xfer(bus, bus->force_bit, msgs, num); | 322 | ret = intel_i2c_quirk_xfer(bus, msgs, num); |
323 | } | ||
324 | out: | 324 | out: |
325 | mutex_unlock(&dev_priv->gmbus_mutex); | 325 | mutex_unlock(&dev_priv->gmbus_mutex); |
326 | return ret; | 326 | return ret; |
@@ -328,14 +328,8 @@ out: | |||
328 | 328 | ||
329 | static u32 gmbus_func(struct i2c_adapter *adapter) | 329 | static u32 gmbus_func(struct i2c_adapter *adapter) |
330 | { | 330 | { |
331 | struct intel_gmbus *bus = container_of(adapter, | 331 | return i2c_bit_algo.functionality(adapter) & |
332 | struct intel_gmbus, | 332 | (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | |
333 | adapter); | ||
334 | |||
335 | if (bus->force_bit) | ||
336 | i2c_bit_algo.functionality(bus->force_bit); | ||
337 | |||
338 | return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | ||
339 | /* I2C_FUNC_10BIT_ADDR | */ | 333 | /* I2C_FUNC_10BIT_ADDR | */ |
340 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | | 334 | I2C_FUNC_SMBUS_READ_BLOCK_DATA | |
341 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL); | 335 | I2C_FUNC_SMBUS_BLOCK_PROC_CALL); |
@@ -393,8 +387,11 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
393 | /* By default use a conservative clock rate */ | 387 | /* By default use a conservative clock rate */ |
394 | bus->reg0 = i | GMBUS_RATE_100KHZ; | 388 | bus->reg0 = i | GMBUS_RATE_100KHZ; |
395 | 389 | ||
390 | bus->has_gpio = intel_gpio_setup(bus, i); | ||
391 | |||
396 | /* XXX force bit banging until GMBUS is fully debugged */ | 392 | /* XXX force bit banging until GMBUS is fully debugged */ |
397 | bus->force_bit = intel_gpio_create(bus, i); | 393 | if (bus->has_gpio) |
394 | bus->force_bit = true; | ||
398 | } | 395 | } |
399 | 396 | ||
400 | intel_i2c_reset(dev_priv->dev); | 397 | intel_i2c_reset(dev_priv->dev); |
@@ -422,16 +419,8 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit) | |||
422 | { | 419 | { |
423 | struct intel_gmbus *bus = to_intel_gmbus(adapter); | 420 | struct intel_gmbus *bus = to_intel_gmbus(adapter); |
424 | 421 | ||
425 | if (force_bit) { | 422 | if (bus->has_gpio) |
426 | if (bus->force_bit == NULL) { | 423 | bus->force_bit = force_bit; |
427 | bus->force_bit = intel_gpio_create(bus, | ||
428 | bus->reg0 & 0xff); | ||
429 | } | ||
430 | } else { | ||
431 | if (bus->force_bit) { | ||
432 | bus->force_bit = NULL; | ||
433 | } | ||
434 | } | ||
435 | } | 424 | } |
436 | 425 | ||
437 | void intel_teardown_gmbus(struct drm_device *dev) | 426 | void intel_teardown_gmbus(struct drm_device *dev) |