diff options
-rw-r--r-- | Documentation/hwmon/ltc4215 | 7 | ||||
-rw-r--r-- | Documentation/hwmon/ltc4245 | 7 | ||||
-rw-r--r-- | drivers/hwmon/ltc4215.c | 47 | ||||
-rw-r--r-- | drivers/hwmon/ltc4245.c | 131 |
4 files changed, 18 insertions, 174 deletions
diff --git a/Documentation/hwmon/ltc4215 b/Documentation/hwmon/ltc4215 index 2e6a21eb656c..c196a1846259 100644 --- a/Documentation/hwmon/ltc4215 +++ b/Documentation/hwmon/ltc4215 | |||
@@ -22,12 +22,13 @@ Usage Notes | |||
22 | ----------- | 22 | ----------- |
23 | 23 | ||
24 | This driver does not probe for LTC4215 devices, due to the fact that some | 24 | This driver does not probe for LTC4215 devices, due to the fact that some |
25 | of the possible addresses are unfriendly to probing. You will need to use | 25 | of the possible addresses are unfriendly to probing. You will have to |
26 | the "force" parameter to tell the driver where to find the device. | 26 | instantiate the devices explicitly. |
27 | 27 | ||
28 | Example: the following will load the driver for an LTC4215 at address 0x44 | 28 | Example: the following will load the driver for an LTC4215 at address 0x44 |
29 | on I2C bus #0: | 29 | on I2C bus #0: |
30 | $ modprobe ltc4215 force=0,0x44 | 30 | $ modprobe ltc4215 |
31 | $ echo ltc4215 0x44 > /sys/bus/i2c/devices/i2c-0/new_device | ||
31 | 32 | ||
32 | 33 | ||
33 | Sysfs entries | 34 | Sysfs entries |
diff --git a/Documentation/hwmon/ltc4245 b/Documentation/hwmon/ltc4245 index bae7a3adc5d8..02838a47d862 100644 --- a/Documentation/hwmon/ltc4245 +++ b/Documentation/hwmon/ltc4245 | |||
@@ -23,12 +23,13 @@ Usage Notes | |||
23 | ----------- | 23 | ----------- |
24 | 24 | ||
25 | This driver does not probe for LTC4245 devices, due to the fact that some | 25 | This driver does not probe for LTC4245 devices, due to the fact that some |
26 | of the possible addresses are unfriendly to probing. You will need to use | 26 | of the possible addresses are unfriendly to probing. You will have to |
27 | the "force" parameter to tell the driver where to find the device. | 27 | instantiate the devices explicitly. |
28 | 28 | ||
29 | Example: the following will load the driver for an LTC4245 at address 0x23 | 29 | Example: the following will load the driver for an LTC4245 at address 0x23 |
30 | on I2C bus #1: | 30 | on I2C bus #1: |
31 | $ modprobe ltc4245 force=1,0x23 | 31 | $ modprobe ltc4245 |
32 | $ echo ltc4245 0x23 > /sys/bus/i2c/devices/i2c-1/new_device | ||
32 | 33 | ||
33 | 34 | ||
34 | Sysfs entries | 35 | Sysfs entries |
diff --git a/drivers/hwmon/ltc4215.c b/drivers/hwmon/ltc4215.c index 6c9a04136e0a..00d975eb5b83 100644 --- a/drivers/hwmon/ltc4215.c +++ b/drivers/hwmon/ltc4215.c | |||
@@ -20,11 +20,6 @@ | |||
20 | #include <linux/hwmon.h> | 20 | #include <linux/hwmon.h> |
21 | #include <linux/hwmon-sysfs.h> | 21 | #include <linux/hwmon-sysfs.h> |
22 | 22 | ||
23 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
24 | |||
25 | /* Insmod parameters */ | ||
26 | I2C_CLIENT_INSMOD_1(ltc4215); | ||
27 | |||
28 | /* Here are names of the chip's registers (a.k.a. commands) */ | 23 | /* Here are names of the chip's registers (a.k.a. commands) */ |
29 | enum ltc4215_cmd { | 24 | enum ltc4215_cmd { |
30 | LTC4215_CONTROL = 0x00, /* rw */ | 25 | LTC4215_CONTROL = 0x00, /* rw */ |
@@ -246,9 +241,13 @@ static const struct attribute_group ltc4215_group = { | |||
246 | static int ltc4215_probe(struct i2c_client *client, | 241 | static int ltc4215_probe(struct i2c_client *client, |
247 | const struct i2c_device_id *id) | 242 | const struct i2c_device_id *id) |
248 | { | 243 | { |
244 | struct i2c_adapter *adapter = client->adapter; | ||
249 | struct ltc4215_data *data; | 245 | struct ltc4215_data *data; |
250 | int ret; | 246 | int ret; |
251 | 247 | ||
248 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
249 | return -ENODEV; | ||
250 | |||
252 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 251 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
253 | if (!data) { | 252 | if (!data) { |
254 | ret = -ENOMEM; | 253 | ret = -ENOMEM; |
@@ -294,56 +293,20 @@ static int ltc4215_remove(struct i2c_client *client) | |||
294 | return 0; | 293 | return 0; |
295 | } | 294 | } |
296 | 295 | ||
297 | static int ltc4215_detect(struct i2c_client *client, | ||
298 | int kind, | ||
299 | struct i2c_board_info *info) | ||
300 | { | ||
301 | struct i2c_adapter *adapter = client->adapter; | ||
302 | |||
303 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
304 | return -ENODEV; | ||
305 | |||
306 | if (kind < 0) { /* probed detection - check the chip type */ | ||
307 | s32 v; /* 8 bits from the chip, or -ERRNO */ | ||
308 | |||
309 | /* | ||
310 | * Register 0x01 bit b7 is reserved, expect 0 | ||
311 | * Register 0x03 bit b6 and b7 are reserved, expect 0 | ||
312 | */ | ||
313 | v = i2c_smbus_read_byte_data(client, LTC4215_ALERT); | ||
314 | if (v < 0 || (v & (1 << 7)) != 0) | ||
315 | return -ENODEV; | ||
316 | |||
317 | v = i2c_smbus_read_byte_data(client, LTC4215_FAULT); | ||
318 | if (v < 0 || (v & ((1 << 6) | (1 << 7))) != 0) | ||
319 | return -ENODEV; | ||
320 | } | ||
321 | |||
322 | strlcpy(info->type, "ltc4215", I2C_NAME_SIZE); | ||
323 | dev_info(&adapter->dev, "ltc4215 %s at address 0x%02x\n", | ||
324 | kind < 0 ? "probed" : "forced", | ||
325 | client->addr); | ||
326 | |||
327 | return 0; | ||
328 | } | ||
329 | |||
330 | static const struct i2c_device_id ltc4215_id[] = { | 296 | static const struct i2c_device_id ltc4215_id[] = { |
331 | { "ltc4215", ltc4215 }, | 297 | { "ltc4215", 0 }, |
332 | { } | 298 | { } |
333 | }; | 299 | }; |
334 | MODULE_DEVICE_TABLE(i2c, ltc4215_id); | 300 | MODULE_DEVICE_TABLE(i2c, ltc4215_id); |
335 | 301 | ||
336 | /* This is the driver that will be inserted */ | 302 | /* This is the driver that will be inserted */ |
337 | static struct i2c_driver ltc4215_driver = { | 303 | static struct i2c_driver ltc4215_driver = { |
338 | .class = I2C_CLASS_HWMON, | ||
339 | .driver = { | 304 | .driver = { |
340 | .name = "ltc4215", | 305 | .name = "ltc4215", |
341 | }, | 306 | }, |
342 | .probe = ltc4215_probe, | 307 | .probe = ltc4215_probe, |
343 | .remove = ltc4215_remove, | 308 | .remove = ltc4215_remove, |
344 | .id_table = ltc4215_id, | 309 | .id_table = ltc4215_id, |
345 | .detect = ltc4215_detect, | ||
346 | .address_data = &addr_data, | ||
347 | }; | 310 | }; |
348 | 311 | ||
349 | static int __init ltc4215_init(void) | 312 | static int __init ltc4215_init(void) |
diff --git a/drivers/hwmon/ltc4245.c b/drivers/hwmon/ltc4245.c index e38964333612..65c232a9d0c5 100644 --- a/drivers/hwmon/ltc4245.c +++ b/drivers/hwmon/ltc4245.c | |||
@@ -22,15 +22,6 @@ | |||
22 | #include <linux/hwmon.h> | 22 | #include <linux/hwmon.h> |
23 | #include <linux/hwmon-sysfs.h> | 23 | #include <linux/hwmon-sysfs.h> |
24 | 24 | ||
25 | /* Valid addresses are 0x20 - 0x3f | ||
26 | * | ||
27 | * For now, we do not probe, since some of these addresses | ||
28 | * are known to be unfriendly to probing */ | ||
29 | static const unsigned short normal_i2c[] = { I2C_CLIENT_END }; | ||
30 | |||
31 | /* Insmod parameters */ | ||
32 | I2C_CLIENT_INSMOD_1(ltc4245); | ||
33 | |||
34 | /* Here are names of the chip's registers (a.k.a. commands) */ | 25 | /* Here are names of the chip's registers (a.k.a. commands) */ |
35 | enum ltc4245_cmd { | 26 | enum ltc4245_cmd { |
36 | LTC4245_STATUS = 0x00, /* readonly */ | 27 | LTC4245_STATUS = 0x00, /* readonly */ |
@@ -369,9 +360,13 @@ static const struct attribute_group ltc4245_group = { | |||
369 | static int ltc4245_probe(struct i2c_client *client, | 360 | static int ltc4245_probe(struct i2c_client *client, |
370 | const struct i2c_device_id *id) | 361 | const struct i2c_device_id *id) |
371 | { | 362 | { |
363 | struct i2c_adapter *adapter = client->adapter; | ||
372 | struct ltc4245_data *data; | 364 | struct ltc4245_data *data; |
373 | int ret; | 365 | int ret; |
374 | 366 | ||
367 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
368 | return -ENODEV; | ||
369 | |||
375 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 370 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
376 | if (!data) { | 371 | if (!data) { |
377 | ret = -ENOMEM; | 372 | ret = -ENOMEM; |
@@ -418,136 +413,20 @@ static int ltc4245_remove(struct i2c_client *client) | |||
418 | return 0; | 413 | return 0; |
419 | } | 414 | } |
420 | 415 | ||
421 | /* Check that some bits in a control register appear at all possible | ||
422 | * locations without changing value | ||
423 | * | ||
424 | * @client: the i2c client to use | ||
425 | * @reg: the register to read | ||
426 | * @bits: the bits to check (0xff checks all bits, | ||
427 | * 0x03 checks only the last two bits) | ||
428 | * | ||
429 | * return -ERRNO if the register read failed | ||
430 | * return -ENODEV if the register value doesn't stay constant at all | ||
431 | * possible addresses | ||
432 | * | ||
433 | * return 0 for success | ||
434 | */ | ||
435 | static int ltc4245_check_control_reg(struct i2c_client *client, u8 reg, u8 bits) | ||
436 | { | ||
437 | int i; | ||
438 | s32 v, voff1, voff2; | ||
439 | |||
440 | /* Read register and check for error */ | ||
441 | v = i2c_smbus_read_byte_data(client, reg); | ||
442 | if (v < 0) | ||
443 | return v; | ||
444 | |||
445 | v &= bits; | ||
446 | |||
447 | for (i = 0x00; i < 0xff; i += 0x20) { | ||
448 | |||
449 | voff1 = i2c_smbus_read_byte_data(client, reg + i); | ||
450 | if (voff1 < 0) | ||
451 | return voff1; | ||
452 | |||
453 | voff2 = i2c_smbus_read_byte_data(client, reg + i + 0x08); | ||
454 | if (voff2 < 0) | ||
455 | return voff2; | ||
456 | |||
457 | voff1 &= bits; | ||
458 | voff2 &= bits; | ||
459 | |||
460 | if (v != voff1 || v != voff2) | ||
461 | return -ENODEV; | ||
462 | } | ||
463 | |||
464 | return 0; | ||
465 | } | ||
466 | |||
467 | static int ltc4245_detect(struct i2c_client *client, | ||
468 | int kind, | ||
469 | struct i2c_board_info *info) | ||
470 | { | ||
471 | struct i2c_adapter *adapter = client->adapter; | ||
472 | |||
473 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
474 | return -ENODEV; | ||
475 | |||
476 | if (kind < 0) { /* probed detection - check the chip type */ | ||
477 | s32 v; /* 8 bits from the chip, or -ERRNO */ | ||
478 | |||
479 | /* Chip registers 0x00-0x07 are control registers | ||
480 | * Chip registers 0x10-0x1f are data registers | ||
481 | * | ||
482 | * Address bits b7-b5 are ignored. This makes the chip "repeat" | ||
483 | * in steps of 0x20. Any control registers should appear with | ||
484 | * the same values across all duplicated addresses. | ||
485 | * | ||
486 | * Register 0x02 bit b2 is reserved, expect 0 | ||
487 | * Register 0x07 bits b7 to b4 are reserved, expect 0 | ||
488 | * | ||
489 | * Registers 0x01, 0x02 are control registers and should not | ||
490 | * change on their own. | ||
491 | * | ||
492 | * Register 0x06 bits b6 and b7 are control bits, and should | ||
493 | * not change on their own. | ||
494 | * | ||
495 | * Register 0x07 bits b3 to b0 are control bits, and should | ||
496 | * not change on their own. | ||
497 | */ | ||
498 | |||
499 | /* read register 0x02 reserved bit, expect 0 */ | ||
500 | v = i2c_smbus_read_byte_data(client, LTC4245_CONTROL); | ||
501 | if (v < 0 || (v & 0x04) != 0) | ||
502 | return -ENODEV; | ||
503 | |||
504 | /* read register 0x07 reserved bits, expect 0 */ | ||
505 | v = i2c_smbus_read_byte_data(client, LTC4245_ADCADR); | ||
506 | if (v < 0 || (v & 0xf0) != 0) | ||
507 | return -ENODEV; | ||
508 | |||
509 | /* check that the alert register appears at all locations */ | ||
510 | if (ltc4245_check_control_reg(client, LTC4245_ALERT, 0xff)) | ||
511 | return -ENODEV; | ||
512 | |||
513 | /* check that the control register appears at all locations */ | ||
514 | if (ltc4245_check_control_reg(client, LTC4245_CONTROL, 0xff)) | ||
515 | return -ENODEV; | ||
516 | |||
517 | /* check that register 0x06 bits b6 and b7 stay constant */ | ||
518 | if (ltc4245_check_control_reg(client, LTC4245_GPIO, 0xc0)) | ||
519 | return -ENODEV; | ||
520 | |||
521 | /* check that register 0x07 bits b3-b0 stay constant */ | ||
522 | if (ltc4245_check_control_reg(client, LTC4245_ADCADR, 0x0f)) | ||
523 | return -ENODEV; | ||
524 | } | ||
525 | |||
526 | strlcpy(info->type, "ltc4245", I2C_NAME_SIZE); | ||
527 | dev_info(&adapter->dev, "ltc4245 %s at address 0x%02x\n", | ||
528 | kind < 0 ? "probed" : "forced", | ||
529 | client->addr); | ||
530 | |||
531 | return 0; | ||
532 | } | ||
533 | |||
534 | static const struct i2c_device_id ltc4245_id[] = { | 416 | static const struct i2c_device_id ltc4245_id[] = { |
535 | { "ltc4245", ltc4245 }, | 417 | { "ltc4245", 0 }, |
536 | { } | 418 | { } |
537 | }; | 419 | }; |
538 | MODULE_DEVICE_TABLE(i2c, ltc4245_id); | 420 | MODULE_DEVICE_TABLE(i2c, ltc4245_id); |
539 | 421 | ||
540 | /* This is the driver that will be inserted */ | 422 | /* This is the driver that will be inserted */ |
541 | static struct i2c_driver ltc4245_driver = { | 423 | static struct i2c_driver ltc4245_driver = { |
542 | .class = I2C_CLASS_HWMON, | ||
543 | .driver = { | 424 | .driver = { |
544 | .name = "ltc4245", | 425 | .name = "ltc4245", |
545 | }, | 426 | }, |
546 | .probe = ltc4245_probe, | 427 | .probe = ltc4245_probe, |
547 | .remove = ltc4245_remove, | 428 | .remove = ltc4245_remove, |
548 | .id_table = ltc4245_id, | 429 | .id_table = ltc4245_id, |
549 | .detect = ltc4245_detect, | ||
550 | .address_data = &addr_data, | ||
551 | }; | 430 | }; |
552 | 431 | ||
553 | static int __init ltc4245_init(void) | 432 | static int __init ltc4245_init(void) |