|
@@ -34,18 +34,19 @@
|
|
|
#include <drm/i915_drm.h>
|
|
|
#include "i915_drv.h"
|
|
|
|
|
|
-struct gmbus_port {
|
|
|
+struct gmbus_pin {
|
|
|
const char *name;
|
|
|
int reg;
|
|
|
};
|
|
|
|
|
|
-static const struct gmbus_port gmbus_ports[] = {
|
|
|
- { "ssc", GPIOB },
|
|
|
- { "vga", GPIOA },
|
|
|
- { "panel", GPIOC },
|
|
|
- { "dpc", GPIOD },
|
|
|
- { "dpb", GPIOE },
|
|
|
- { "dpd", GPIOF },
|
|
|
+/* Map gmbus pin pairs to names and registers. */
|
|
|
+static const struct gmbus_pin gmbus_pins[] = {
|
|
|
+ [GMBUS_PIN_SSC] = { "ssc", GPIOB },
|
|
|
+ [GMBUS_PIN_VGADDC] = { "vga", GPIOA },
|
|
|
+ [GMBUS_PIN_PANEL] = { "panel", GPIOC },
|
|
|
+ [GMBUS_PIN_DPC] = { "dpc", GPIOD },
|
|
|
+ [GMBUS_PIN_DPB] = { "dpb", GPIOE },
|
|
|
+ [GMBUS_PIN_DPD] = { "dpd", GPIOF },
|
|
|
};
|
|
|
|
|
|
/* Intel GPIO access functions */
|
|
@@ -182,15 +183,14 @@ intel_gpio_post_xfer(struct i2c_adapter *adapter)
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-intel_gpio_setup(struct intel_gmbus *bus, u32 pin)
|
|
|
+intel_gpio_setup(struct intel_gmbus *bus, unsigned int pin)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = bus->dev_priv;
|
|
|
struct i2c_algo_bit_data *algo;
|
|
|
|
|
|
algo = &bus->bit_algo;
|
|
|
|
|
|
- /* -1 to map pin pair to gmbus index */
|
|
|
- bus->gpio_reg = dev_priv->gpio_mmio_base + gmbus_ports[pin - 1].reg;
|
|
|
+ bus->gpio_reg = dev_priv->gpio_mmio_base + gmbus_pins[pin].reg;
|
|
|
|
|
|
bus->adapter.algo_data = algo;
|
|
|
algo->setsda = set_data;
|
|
@@ -517,7 +517,9 @@ static const struct i2c_algorithm gmbus_algorithm = {
|
|
|
int intel_setup_gmbus(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
- int ret, i;
|
|
|
+ struct intel_gmbus *bus;
|
|
|
+ unsigned int pin;
|
|
|
+ int ret;
|
|
|
|
|
|
if (HAS_PCH_NOP(dev))
|
|
|
return 0;
|
|
@@ -531,16 +533,18 @@ int intel_setup_gmbus(struct drm_device *dev)
|
|
|
mutex_init(&dev_priv->gmbus_mutex);
|
|
|
init_waitqueue_head(&dev_priv->gmbus_wait_queue);
|
|
|
|
|
|
- for (i = 0; i < GMBUS_NUM_PORTS; i++) {
|
|
|
- struct intel_gmbus *bus = &dev_priv->gmbus[i];
|
|
|
- u32 port = i + 1; /* +1 to map gmbus index to pin pair */
|
|
|
+ for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
|
|
|
+ if (!intel_gmbus_is_valid_pin(pin))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ bus = &dev_priv->gmbus[pin];
|
|
|
|
|
|
bus->adapter.owner = THIS_MODULE;
|
|
|
bus->adapter.class = I2C_CLASS_DDC;
|
|
|
snprintf(bus->adapter.name,
|
|
|
sizeof(bus->adapter.name),
|
|
|
"i915 gmbus %s",
|
|
|
- gmbus_ports[i].name);
|
|
|
+ gmbus_pins[pin].name);
|
|
|
|
|
|
bus->adapter.dev.parent = &dev->pdev->dev;
|
|
|
bus->dev_priv = dev_priv;
|
|
@@ -548,13 +552,13 @@ int intel_setup_gmbus(struct drm_device *dev)
|
|
|
bus->adapter.algo = &gmbus_algorithm;
|
|
|
|
|
|
/* By default use a conservative clock rate */
|
|
|
- bus->reg0 = port | GMBUS_RATE_100KHZ;
|
|
|
+ bus->reg0 = pin | GMBUS_RATE_100KHZ;
|
|
|
|
|
|
/* gmbus seems to be broken on i830 */
|
|
|
if (IS_I830(dev))
|
|
|
bus->force_bit = 1;
|
|
|
|
|
|
- intel_gpio_setup(bus, port);
|
|
|
+ intel_gpio_setup(bus, pin);
|
|
|
|
|
|
ret = i2c_add_adapter(&bus->adapter);
|
|
|
if (ret)
|
|
@@ -566,8 +570,11 @@ int intel_setup_gmbus(struct drm_device *dev)
|
|
|
return 0;
|
|
|
|
|
|
err:
|
|
|
- while (--i) {
|
|
|
- struct intel_gmbus *bus = &dev_priv->gmbus[i];
|
|
|
+ while (--pin) {
|
|
|
+ if (!intel_gmbus_is_valid_pin(pin))
|
|
|
+ continue;
|
|
|
+
|
|
|
+ bus = &dev_priv->gmbus[pin];
|
|
|
i2c_del_adapter(&bus->adapter);
|
|
|
}
|
|
|
return ret;
|
|
@@ -576,10 +583,10 @@ err:
|
|
|
struct i2c_adapter *intel_gmbus_get_adapter(struct drm_i915_private *dev_priv,
|
|
|
unsigned int pin)
|
|
|
{
|
|
|
- WARN_ON(!intel_gmbus_is_valid_pin(pin));
|
|
|
- /* -1 to map pin pair to gmbus index */
|
|
|
- return (intel_gmbus_is_valid_pin(pin)) ?
|
|
|
- &dev_priv->gmbus[pin - 1].adapter : NULL;
|
|
|
+ if (WARN_ON(!intel_gmbus_is_valid_pin(pin)))
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ return &dev_priv->gmbus[pin].adapter;
|
|
|
}
|
|
|
|
|
|
void intel_gmbus_set_speed(struct i2c_adapter *adapter, int speed)
|
|
@@ -602,10 +609,14 @@ void intel_gmbus_force_bit(struct i2c_adapter *adapter, bool force_bit)
|
|
|
void intel_teardown_gmbus(struct drm_device *dev)
|
|
|
{
|
|
|
struct drm_i915_private *dev_priv = dev->dev_private;
|
|
|
- int i;
|
|
|
+ struct intel_gmbus *bus;
|
|
|
+ unsigned int pin;
|
|
|
+
|
|
|
+ for (pin = 0; pin < ARRAY_SIZE(dev_priv->gmbus); pin++) {
|
|
|
+ if (!intel_gmbus_is_valid_pin(pin))
|
|
|
+ continue;
|
|
|
|
|
|
- for (i = 0; i < GMBUS_NUM_PORTS; i++) {
|
|
|
- struct intel_gmbus *bus = &dev_priv->gmbus[i];
|
|
|
+ bus = &dev_priv->gmbus[pin];
|
|
|
i2c_del_adapter(&bus->adapter);
|
|
|
}
|
|
|
}
|