aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau
diff options
context:
space:
mode:
authorFrancisco Jerez <currojerez@riseup.net>2010-09-23 15:00:40 -0400
committerBen Skeggs <bskeggs@redhat.com>2010-09-24 02:29:36 -0400
commit66146da06643d8ee89bc5255fb0254006e3d0e79 (patch)
tree7cc84d257544047bacb3aa618dd39ab7fc20180c /drivers/gpu/drm/nouveau
parent8155cac489eb8cc6fd96b9bdefacdf5a56e6ea32 (diff)
drm/nouveau: Add support for I2C hardware monitoring devices.
Signed-off-by: Francisco Jerez <currojerez@riseup.net> Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.c8
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_i2c.h5
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_temp.c48
-rw-r--r--drivers/gpu/drm/nouveau/nv04_dfp.c2
-rw-r--r--drivers/gpu/drm/nouveau/nv04_tv.c4
5 files changed, 58 insertions, 9 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c
index 84614858728..fdd7e3de79c 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.c
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c
@@ -299,7 +299,10 @@ nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr)
299 299
300int 300int
301nouveau_i2c_identify(struct drm_device *dev, const char *what, 301nouveau_i2c_identify(struct drm_device *dev, const char *what,
302 struct i2c_board_info *info, int index) 302 struct i2c_board_info *info,
303 bool (*match)(struct nouveau_i2c_chan *,
304 struct i2c_board_info *),
305 int index)
303{ 306{
304 struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index); 307 struct nouveau_i2c_chan *i2c = nouveau_i2c_find(dev, index);
305 int i; 308 int i;
@@ -307,7 +310,8 @@ nouveau_i2c_identify(struct drm_device *dev, const char *what,
307 NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index); 310 NV_DEBUG(dev, "Probing %ss on I2C bus: %d\n", what, index);
308 311
309 for (i = 0; info[i].addr; i++) { 312 for (i = 0; info[i].addr; i++) {
310 if (nouveau_probe_i2c_addr(i2c, info[i].addr)) { 313 if (nouveau_probe_i2c_addr(i2c, info[i].addr) &&
314 (!match || match(i2c, &info[i]))) {
311 NV_INFO(dev, "Detected %s: %s\n", what, info[i].type); 315 NV_INFO(dev, "Detected %s: %s\n", what, info[i].type);
312 return i; 316 return i;
313 } 317 }
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.h b/drivers/gpu/drm/nouveau/nouveau_i2c.h
index f71cb32f757..c77a6ba66b7 100644
--- a/drivers/gpu/drm/nouveau/nouveau_i2c.h
+++ b/drivers/gpu/drm/nouveau/nouveau_i2c.h
@@ -44,7 +44,10 @@ void nouveau_i2c_fini(struct drm_device *, struct dcb_i2c_entry *);
44struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); 44struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index);
45bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr); 45bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr);
46int nouveau_i2c_identify(struct drm_device *dev, const char *what, 46int nouveau_i2c_identify(struct drm_device *dev, const char *what,
47 struct i2c_board_info *info, int index); 47 struct i2c_board_info *info,
48 bool (*match)(struct nouveau_i2c_chan *,
49 struct i2c_board_info *),
50 int index);
48 51
49extern const struct i2c_algorithm nouveau_dp_i2c_algo; 52extern const struct i2c_algorithm nouveau_dp_i2c_algo;
50 53
diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c
index 2f7785ca4e4..f9eda87d177 100644
--- a/drivers/gpu/drm/nouveau/nouveau_temp.c
+++ b/drivers/gpu/drm/nouveau/nouveau_temp.c
@@ -235,6 +235,48 @@ nouveau_temp_safety_checks(struct drm_device *dev)
235 temps->fan_boost = 40; 235 temps->fan_boost = 40;
236} 236}
237 237
238static bool
239probe_monitoring_device(struct nouveau_i2c_chan *i2c,
240 struct i2c_board_info *info)
241{
242 char modalias[16] = "i2c:";
243 struct i2c_client *client;
244
245 strlcat(modalias, info->type, sizeof(modalias));
246 request_module(modalias);
247
248 client = i2c_new_device(&i2c->adapter, info);
249 if (!client)
250 return false;
251
252 if (!client->driver || client->driver->detect(client, info)) {
253 i2c_unregister_device(client);
254 return false;
255 }
256
257 return true;
258}
259
260static void
261nouveau_temp_probe_i2c(struct drm_device *dev)
262{
263 struct drm_nouveau_private *dev_priv = dev->dev_private;
264 struct dcb_table *dcb = &dev_priv->vbios.dcb;
265 struct i2c_board_info info[] = {
266 { I2C_BOARD_INFO("w83l785ts", 0x2d) },
267 { I2C_BOARD_INFO("w83781d", 0x2d) },
268 { I2C_BOARD_INFO("f75375", 0x2e) },
269 { I2C_BOARD_INFO("adt7473", 0x2e) },
270 { I2C_BOARD_INFO("lm99", 0x4c) },
271 { }
272 };
273 int idx = (dcb->version >= 0x40 ?
274 dcb->i2c_default_indices & 0xf : 2);
275
276 nouveau_i2c_identify(dev, "monitoring device", info,
277 probe_monitoring_device, idx);
278}
279
238void 280void
239nouveau_temp_init(struct drm_device *dev) 281nouveau_temp_init(struct drm_device *dev)
240{ 282{
@@ -253,11 +295,11 @@ nouveau_temp_init(struct drm_device *dev)
253 temp = ROMPTR(bios, P.data[16]); 295 temp = ROMPTR(bios, P.data[16]);
254 else 296 else
255 NV_WARN(dev, "unknown temp for BIT P %d\n", P.version); 297 NV_WARN(dev, "unknown temp for BIT P %d\n", P.version);
256 } else { 298
257 NV_WARN(dev, "BMP entry unknown for temperature table.\n"); 299 nouveau_temp_vbios_parse(dev, temp);
258 } 300 }
259 301
260 nouveau_temp_vbios_parse(dev, temp); 302 nouveau_temp_probe_i2c(dev);
261} 303}
262 304
263void 305void
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c
index e331b4faeb1..4b4f9aabde7 100644
--- a/drivers/gpu/drm/nouveau/nv04_dfp.c
+++ b/drivers/gpu/drm/nouveau/nv04_dfp.c
@@ -635,7 +635,7 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder)
635 get_tmds_slave(encoder)) 635 get_tmds_slave(encoder))
636 return; 636 return;
637 637
638 type = nouveau_i2c_identify(dev, "TMDS transmitter", info, 2); 638 type = nouveau_i2c_identify(dev, "TMDS transmitter", info, NULL, 2);
639 if (type < 0) 639 if (type < 0)
640 return; 640 return;
641 641
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c
index 0b5d012d7c2..c8dc8a376ad 100644
--- a/drivers/gpu/drm/nouveau/nv04_tv.c
+++ b/drivers/gpu/drm/nouveau/nv04_tv.c
@@ -49,8 +49,8 @@ static struct i2c_board_info nv04_tv_encoder_info[] = {
49 49
50int nv04_tv_identify(struct drm_device *dev, int i2c_index) 50int nv04_tv_identify(struct drm_device *dev, int i2c_index)
51{ 51{
52 return nouveau_i2c_identify(dev, "TV encoder", 52 return nouveau_i2c_identify(dev, "TV encoder", nv04_tv_encoder_info,
53 nv04_tv_encoder_info, i2c_index); 53 NULL, i2c_index);
54} 54}
55 55
56 56