aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-02-14 12:58:49 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-02-29 14:53:36 -0500
commitf6f808c8e1c4a3b7e3e0a6cb81541ec615aeb5fd (patch)
tree1755f20d63cc3066a16263961272fbd3f6b077c5 /drivers/gpu/drm
parentc167a6fc6ed78a300c29181a6caf9ae1b9993289 (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.h3
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c51
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
302struct intel_gmbus { 302struct 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
143static struct i2c_adapter * 143static bool
144intel_gpio_create(struct intel_gmbus *bus, u32 pin) 144intel_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
180static int 180static int
181intel_i2c_quirk_xfer(struct intel_gmbus *bus, 181intel_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 }
324out: 324out:
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
329static u32 gmbus_func(struct i2c_adapter *adapter) 329static 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
437void intel_teardown_gmbus(struct drm_device *dev) 426void intel_teardown_gmbus(struct drm_device *dev)