diff options
author | Francisco Jerez <currojerez@riseup.net> | 2010-09-23 15:00:40 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-09-24 02:29:36 -0400 |
commit | 66146da06643d8ee89bc5255fb0254006e3d0e79 (patch) | |
tree | 7cc84d257544047bacb3aa618dd39ab7fc20180c /drivers/gpu/drm/nouveau | |
parent | 8155cac489eb8cc6fd96b9bdefacdf5a56e6ea32 (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.c | 8 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_i2c.h | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_temp.c | 48 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_dfp.c | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv04_tv.c | 4 |
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 | ||
300 | int | 300 | int |
301 | nouveau_i2c_identify(struct drm_device *dev, const char *what, | 301 | nouveau_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 *); | |||
44 | struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); | 44 | struct nouveau_i2c_chan *nouveau_i2c_find(struct drm_device *, int index); |
45 | bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr); | 45 | bool nouveau_probe_i2c_addr(struct nouveau_i2c_chan *i2c, int addr); |
46 | int nouveau_i2c_identify(struct drm_device *dev, const char *what, | 46 | int 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 | ||
49 | extern const struct i2c_algorithm nouveau_dp_i2c_algo; | 52 | extern 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 | ||
238 | static bool | ||
239 | probe_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 | |||
260 | static void | ||
261 | nouveau_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 | |||
238 | void | 280 | void |
239 | nouveau_temp_init(struct drm_device *dev) | 281 | nouveau_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 | ||
263 | void | 305 | void |
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 | ||
50 | int nv04_tv_identify(struct drm_device *dev, int i2c_index) | 50 | int 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 | ||