summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/nouveau/nouveau_i2c.c
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-07-19 15:55:08 +0200
committerBen Skeggs <bskeggs@redhat.com>2010-07-26 11:42:30 +1000
commit6d416d80f720f71e2dfe903d672bcca071822538 (patch)
tree9b5739051504e8b1674d797c045daffcfc3b6b2a /drivers/gpu/drm/nouveau/nouveau_i2c.c
parent6d6a413aa23c8bc7a5787596e06f3d6d8d4f11c7 (diff)
drm/nouveau: Add some generic I2C gadget detection code.
Clean up and move the external TV encoder detection code to nouveau_i2c.c, it's also going to be useful for external TMDS and DDC detection. Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_i2c.c')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
index 316a3c7e6eb4..97ba89ef42a0 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -278,3 +278,37 @@ nouveau_i2c_find(struct drm_device *dev, int index)
return i2c->chan;
}
+bool
+nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
+{
+ struct i2c_msg msg = {
+ .addr = addr,
+ .len = 0,
+ };
+
+ return i2c_transfer(&i2c->adapter, &msg, 1) == 1;
+}
+
+int
+nouveau_i2c_identify(struct drm_device *dev, const char *what,
+ struct i2c_board_info *info, int index)
+{
+ struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
+ int was_locked, i;
+
+ was_locked = NVLockVgaCrtcs(dev, false);
+ NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
+
+ for (i = 0; info[i].addr; i++) {
+ if (nouveau_probe_i2c_addr(i2c, info[i].addr)) {
+ NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
+ goto out;
+ }
+ }
+
+ NV_DEBUG(dev, "No devices found.\n");
+out:
+ NVLockVgaCrtcs(dev, was_locked);
+
+ return info[i].addr ? i : -ENODEV;
+}