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>
This commit is contained in:
parent
b2469f422f
commit
2be381de0f
|
@ -48,6 +48,7 @@ MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended");
|
||||||
#define W83795_REG_VENDORID 0xfd
|
#define W83795_REG_VENDORID 0xfd
|
||||||
#define W83795_REG_CHIPID 0xfe
|
#define W83795_REG_CHIPID 0xfe
|
||||||
#define W83795_REG_DEVICEID 0xfb
|
#define W83795_REG_DEVICEID 0xfb
|
||||||
|
#define W83795_REG_DEVICEID_A 0xff
|
||||||
|
|
||||||
#define W83795_REG_I2C_ADDR 0xfc
|
#define W83795_REG_I2C_ADDR 0xfc
|
||||||
#define W83795_REG_CONFIG 0x01
|
#define W83795_REG_CONFIG 0x01
|
||||||
|
@ -1684,11 +1685,31 @@ static void w83795_init_client(struct i2c_client *client)
|
||||||
w83795_read(client, W83795_REG_CONFIG) | 0x01);
|
w83795_read(client, W83795_REG_CONFIG) | 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int w83795_get_device_id(struct i2c_client *client)
|
||||||
|
{
|
||||||
|
int device_id;
|
||||||
|
|
||||||
|
device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID);
|
||||||
|
|
||||||
|
/* Special case for rev. A chips; can't be checked first because later
|
||||||
|
revisions emulate this for compatibility */
|
||||||
|
if (device_id < 0 || (device_id & 0xf0) != 0x50) {
|
||||||
|
int alt_id;
|
||||||
|
|
||||||
|
alt_id = i2c_smbus_read_byte_data(client,
|
||||||
|
W83795_REG_DEVICEID_A);
|
||||||
|
if (alt_id == 0x50)
|
||||||
|
device_id = alt_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
return device_id;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return 0 if detection is successful, -ENODEV otherwise */
|
/* Return 0 if detection is successful, -ENODEV otherwise */
|
||||||
static int w83795_detect(struct i2c_client *client,
|
static int w83795_detect(struct i2c_client *client,
|
||||||
struct i2c_board_info *info)
|
struct i2c_board_info *info)
|
||||||
{
|
{
|
||||||
u8 tmp, bank;
|
int bank, vendor_id, device_id, expected, i2c_addr, config;
|
||||||
struct i2c_adapter *adapter = client->adapter;
|
struct i2c_adapter *adapter = client->adapter;
|
||||||
unsigned short address = client->addr;
|
unsigned short address = client->addr;
|
||||||
const char *chip_name;
|
const char *chip_name;
|
||||||
|
@ -1696,32 +1717,44 @@ static int w83795_detect(struct i2c_client *client,
|
||||||
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL);
|
bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL);
|
||||||
|
if (bank < 0 || (bank & 0x7c)) {
|
||||||
|
dev_dbg(&adapter->dev,
|
||||||
|
"w83795: Detection failed at addr 0x%02hx, check %s\n",
|
||||||
|
address, "bank");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
tmp = bank & 0x80 ? 0x5c : 0xa3;
|
|
||||||
/* Check Nuvoton vendor ID */
|
/* Check Nuvoton vendor ID */
|
||||||
if (tmp != i2c_smbus_read_byte_data(client,
|
vendor_id = i2c_smbus_read_byte_data(client, W83795_REG_VENDORID);
|
||||||
W83795_REG_VENDORID)) {
|
expected = bank & 0x80 ? 0x5c : 0xa3;
|
||||||
pr_debug("w83795: Detection failed at check "
|
if (vendor_id != expected) {
|
||||||
"vendor id\n");
|
dev_dbg(&adapter->dev,
|
||||||
|
"w83795: Detection failed at addr 0x%02hx, check %s\n",
|
||||||
|
address, "vendor id");
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check device ID */
|
||||||
|
device_id = w83795_get_device_id(client) |
|
||||||
|
(i2c_smbus_read_byte_data(client, W83795_REG_CHIPID) << 8);
|
||||||
|
if ((device_id >> 4) != 0x795) {
|
||||||
|
dev_dbg(&adapter->dev,
|
||||||
|
"w83795: Detection failed at addr 0x%02hx, check %s\n",
|
||||||
|
address, "device id\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR
|
/* If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR
|
||||||
should match */
|
should match */
|
||||||
if ((bank & 0x07) == 0
|
if ((bank & 0x07) == 0) {
|
||||||
&& (i2c_smbus_read_byte_data(client, W83795_REG_I2C_ADDR) & 0x7f) !=
|
i2c_addr = i2c_smbus_read_byte_data(client,
|
||||||
address) {
|
W83795_REG_I2C_ADDR);
|
||||||
pr_debug("w83795: Detection failed at check "
|
if ((i2c_addr & 0x7f) != address) {
|
||||||
"i2c addr\n");
|
dev_dbg(&adapter->dev,
|
||||||
return -ENODEV;
|
"w83795: Detection failed at addr 0x%02hx, "
|
||||||
}
|
"check %s\n", address, "i2c addr");
|
||||||
|
return -ENODEV;
|
||||||
/* Determine the chip type now */
|
}
|
||||||
if (0x79 != i2c_smbus_read_byte_data(client,
|
|
||||||
W83795_REG_CHIPID)) {
|
|
||||||
pr_debug("w83795: Detection failed at check "
|
|
||||||
"chip id\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check 795 chip type: 795G or 795ADG
|
/* Check 795 chip type: 795G or 795ADG
|
||||||
|
@ -1731,14 +1764,15 @@ static int w83795_detect(struct i2c_client *client,
|
||||||
if ((bank & 0x07) != 0)
|
if ((bank & 0x07) != 0)
|
||||||
i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL,
|
i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL,
|
||||||
bank & ~0x07);
|
bank & ~0x07);
|
||||||
if (W83795_REG_CONFIG_CONFIG48 &
|
config = i2c_smbus_read_byte_data(client, W83795_REG_CONFIG);
|
||||||
i2c_smbus_read_byte_data(client, W83795_REG_CONFIG)) {
|
if (config & W83795_REG_CONFIG_CONFIG48)
|
||||||
chip_name = "w83795adg";
|
chip_name = "w83795adg";
|
||||||
} else {
|
else
|
||||||
chip_name = "w83795g";
|
chip_name = "w83795g";
|
||||||
}
|
|
||||||
|
|
||||||
strlcpy(info->type, chip_name, I2C_NAME_SIZE);
|
strlcpy(info->type, chip_name, I2C_NAME_SIZE);
|
||||||
|
dev_info(&adapter->dev, "Found %s rev. %c at 0x%02hx\n", chip_name,
|
||||||
|
'A' + (device_id & 0xf), address);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue