aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJean Delvare <khali@linux-fr.org>2010-10-28 14:31:45 -0400
committerJean Delvare <khali@endymion.delvare>2010-10-28 14:31:45 -0400
commit2be381de0f1e5e0324e8b373e7a84fc9d25d05d3 (patch)
tree5211865f27cc643d7ec3c867a668740d66a48b60
parentb2469f422f9ee2054359c4ec609c3bdb1f2d52f5 (diff)
hwmon: (w83795) Improve detection routine
Check for additional identification registers. Improve debugging messages on failed detection. Signed-off-by: Jean Delvare <khali@linux-fr.org>
-rw-r--r--drivers/hwmon/w83795.c80
1 files changed, 57 insertions, 23 deletions
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c
index c7f6b1fd0899..6596303566e1 100644
--- a/drivers/hwmon/w83795.c
+++ b/drivers/hwmon/w83795.c
@@ -48,6 +48,7 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
48#define W83795_REG_VENDORID 0xfd 48#define W83795_REG_VENDORID 0xfd
49#define W83795_REG_CHIPID 0xfe 49#define W83795_REG_CHIPID 0xfe
50#define W83795_REG_DEVICEID 0xfb 50#define W83795_REG_DEVICEID 0xfb
51#define W83795_REG_DEVICEID_A 0xff
51 52
52#define W83795_REG_I2C_ADDR 0xfc 53#define W83795_REG_I2C_ADDR 0xfc
53#define W83795_REG_CONFIG 0x01 54#define W83795_REG_CONFIG 0x01
@@ -1684,11 +1685,31 @@ static void w83795_init_client(struct i2c_client *client)
1684 w83795_read(client, W83795_REG_CONFIG) | 0x01); 1685 w83795_read(client, W83795_REG_CONFIG) | 0x01);
1685} 1686}
1686 1687
1688static int w83795_get_device_id(struct i2c_client *client)
1689{
1690 int device_id;
1691
1692 device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID);
1693
1694 /* Special case for rev. A chips; can't be checked first because later
1695 revisions emulate this for compatibility */
1696 if (device_id < 0 || (device_id & 0xf0) != 0x50) {
1697 int alt_id;
1698
1699 alt_id = i2c_smbus_read_byte_data(client,
1700 W83795_REG_DEVICEID_A);
1701 if (alt_id == 0x50)
1702 device_id = alt_id;
1703 }
1704
1705 return device_id;
1706}
1707
1687/* Return 0 if detection is successful, -ENODEV otherwise */ 1708/* Return 0 if detection is successful, -ENODEV otherwise */
1688static int w83795_detect(struct i2c_client *client, 1709static int w83795_detect(struct i2c_client *client,
1689 struct i2c_board_info *info) 1710 struct i2c_board_info *info)
1690{ 1711{
1691 u8 tmp, bank; 1712 int bank, vendor_id, device_id, expected, i2c_addr, config;
1692 struct i2c_adapter *adapter = client->adapter; 1713 struct i2c_adapter *adapter = client->adapter;
1693 unsigned short address = client->addr; 1714 unsigned short address = client->addr;
1694 const char *chip_name; 1715 const char *chip_name;
@@ -1696,32 +1717,44 @@ static int w83795_detect(struct i2c_client *client,
1696 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1717 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1697 return -ENODEV; 1718 return -ENODEV;
1698 bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL); 1719 bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL);
1720 if (bank < 0 || (bank & 0x7c)) {
1721 dev_dbg(&adapter->dev,
1722 "w83795: Detection failed at addr 0x%02hx, check %s\n",
1723 address, "bank");
1724 return -ENODEV;
1725 }
1699 1726
1700 tmp = bank & 0x80 ? 0x5c : 0xa3;
1701 /* Check Nuvoton vendor ID */ 1727 /* Check Nuvoton vendor ID */
1702 if (tmp != i2c_smbus_read_byte_data(client, 1728 vendor_id = i2c_smbus_read_byte_data(client, W83795_REG_VENDORID);
1703 W83795_REG_VENDORID)) { 1729 expected = bank & 0x80 ? 0x5c : 0xa3;
1704 pr_debug("w83795: Detection failed at check " 1730 if (vendor_id != expected) {
1705 "vendor id\n"); 1731 dev_dbg(&adapter->dev,
1732 "w83795: Detection failed at addr 0x%02hx, check %s\n",
1733 address, "vendor id");
1706 return -ENODEV; 1734 return -ENODEV;
1707 } 1735 }
1708 1736
1709 /* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR 1737 /* Check device ID */
1710 should match */ 1738 device_id = w83795_get_device_id(client) |
1711 if ((bank & 0x07) == 0 1739 (i2c_smbus_read_byte_data(client, W83795_REG_CHIPID) << 8);
1712 && (i2c_smbus_read_byte_data(client, W83795_REG_I2C_ADDR) & 0x7f) != 1740 if ((device_id >> 4) != 0x795) {
1713 address) { 1741 dev_dbg(&adapter->dev,
1714 pr_debug("w83795: Detection failed at check " 1742 "w83795: Detection failed at addr 0x%02hx, check %s\n",
1715 "i2c addr\n"); 1743 address, "device id\n");
1716 return -ENODEV; 1744 return -ENODEV;
1717 } 1745 }
1718 1746
1719 /* Determine the chip type now */ 1747 /* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR
1720 if (0x79 != i2c_smbus_read_byte_data(client, 1748 should match */
1721 W83795_REG_CHIPID)) { 1749 if ((bank & 0x07) == 0) {
1722 pr_debug("w83795: Detection failed at check " 1750 i2c_addr = i2c_smbus_read_byte_data(client,
1723 "chip id\n"); 1751 W83795_REG_I2C_ADDR);
1724 return -ENODEV; 1752 if ((i2c_addr & 0x7f) != address) {
1753 dev_dbg(&adapter->dev,
1754 "w83795: Detection failed at addr 0x%02hx, "
1755 "check %s\n", address, "i2c addr");
1756 return -ENODEV;
1757 }
1725 } 1758 }
1726 1759
1727 /* Check 795 chip type: 795G or 795ADG 1760 /* Check 795 chip type: 795G or 795ADG
@@ -1731,14 +1764,15 @@ static int w83795_detect(struct i2c_client *client,
1731 if ((bank & 0x07) != 0) 1764 if ((bank & 0x07) != 0)
1732 i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, 1765 i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL,
1733 bank & ~0x07); 1766 bank & ~0x07);
1734 if (W83795_REG_CONFIG_CONFIG48 & 1767 config = i2c_smbus_read_byte_data(client, W83795_REG_CONFIG);
1735 i2c_smbus_read_byte_data(client, W83795_REG_CONFIG)) { 1768 if (config & W83795_REG_CONFIG_CONFIG48)
1736 chip_name = "w83795adg"; 1769 chip_name = "w83795adg";
1737 } else { 1770 else
1738 chip_name = "w83795g"; 1771 chip_name = "w83795g";
1739 }
1740 1772
1741 strlcpy(info->type, chip_name, I2C_NAME_SIZE); 1773 strlcpy(info->type, chip_name, I2C_NAME_SIZE);
1774 dev_info(&adapter->dev, "Found %s rev. %c at 0x%02hx\n", chip_name,
1775 'A' + (device_id & 0xf), address);
1742 1776
1743 return 0; 1777 return 0;
1744} 1778}