diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_i2c.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_i2c.c | 34 |
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) | |||
278 | return i2c->chan; | 278 | return i2c->chan; |
279 | } | 279 | } |
280 | 280 | ||
281 | bool | ||
282 | nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr) | ||
283 | { | ||
284 | struct i2c_msg msg = { | ||
285 | .addr = addr, | ||
286 | .len = 0, | ||
287 | }; | ||
288 | |||
289 | return i2c_transfer(&i2c->adapter, &msg, 1) == 1; | ||
290 | } | ||
291 | |||
292 | int | ||
293 | nouveau_i2c_identify(struct drm_device *dev, const char *what, | ||
294 | struct i2c_board_info *info, int index) | ||
295 | { | ||
296 | struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index); | ||
297 | int was_locked, i; | ||
298 | |||
299 | was_locked = NVLockVgaCrtcs(dev, false); | ||
300 | NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); | ||
301 | |||
302 | for (i = 0; info[i].addr; i++) { | ||
303 | if (nouveau_probe_i2c_addr(i2c, info[i].addr)) { | ||
304 | NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); | ||
305 | goto out; | ||
306 | } | ||
307 | } | ||
308 | |||
309 | NV_DEBUG(dev, "No devices found.\n"); | ||
310 | out: | ||
311 | NVLockVgaCrtcs(dev, was_locked); | ||
312 | |||
313 | return info[i].addr ? i : -ENODEV; | ||
314 | } | ||