Commit b2469f42 authored by Jean Delvare's avatar Jean Delvare Committed by Jean Delvare

hwmon: (w83795) Refactor bank selection

Move the bank selection code to a separate function, to avoid
duplicating it in read and write functions. Improve error reporting
on register access error.
Signed-off-by: default avatarJean Delvare <khali@linux-fr.org>
parent 093d1a47
...@@ -360,60 +360,67 @@ struct w83795_data { ...@@ -360,60 +360,67 @@ struct w83795_data {
/* /*
* Hardware access * Hardware access
* We assume that nobdody can change the bank outside the driver.
*/ */
/* Ignore the possibility that somebody change bank outside the driver /* Must be called with data->update_lock held, except during initialization */
* Must be called with data->update_lock held, except during initialization */ static int w83795_set_bank(struct i2c_client *client, u8 bank)
static u8 w83795_read(struct i2c_client *client, u16 reg)
{ {
struct w83795_data *data = i2c_get_clientdata(client); struct w83795_data *data = i2c_get_clientdata(client);
u8 res = 0xff; int err;
u8 new_bank = reg >> 8;
/* If the same bank is already set, nothing to do */
new_bank |= data->bank & 0xfc; if ((data->bank & 0x07) == bank)
if (data->bank != new_bank) { return 0;
if (i2c_smbus_write_byte_data
(client, W83795_REG_BANKSEL, new_bank) >= 0) /* Change to new bank, preserve all other bits */
data->bank = new_bank; bank |= data->bank & ~0x07;
else { err = i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, bank);
if (err < 0) {
dev_err(&client->dev, dev_err(&client->dev,
"set bank to %d failed, fall back " "Failed to set bank to %d, err %d\n",
"to bank %d, read reg 0x%x error\n", (int)bank, err);
new_bank, data->bank, reg); return err;
res = 0x0; /* read 0x0 from the chip */
goto END;
}
} }
res = i2c_smbus_read_byte_data(client, reg & 0xff); data->bank = bank;
END:
return res; return 0;
} }
/* Must be called with data->update_lock held, except during initialization */ /* Must be called with data->update_lock held, except during initialization */
static int w83795_write(struct i2c_client *client, u16 reg, u8 value) static u8 w83795_read(struct i2c_client *client, u16 reg)
{ {
struct w83795_data *data = i2c_get_clientdata(client); int err;
int res;
u8 new_bank = reg >> 8; err = w83795_set_bank(client, reg >> 8);
if (err < 0)
new_bank |= data->bank & 0xfc; return 0x00; /* Arbitrary */
if (data->bank != new_bank) {
res = i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, err = i2c_smbus_read_byte_data(client, reg & 0xff);
new_bank); if (err < 0) {
if (res >= 0)
data->bank = new_bank;
else {
dev_err(&client->dev, dev_err(&client->dev,
"set bank to %d failed, fall back " "Failed to read from register 0x%03x, err %d\n",
"to bank %d, write reg 0x%x error\n", (int)reg, err);
new_bank, data->bank, reg); return 0x00; /* Arbitrary */
goto END;
}
} }
return err;
}
res = i2c_smbus_write_byte_data(client, reg & 0xff, value); /* Must be called with data->update_lock held, except during initialization */
END: static int w83795_write(struct i2c_client *client, u16 reg, u8 value)
return res; {
int err;
err = w83795_set_bank(client, reg >> 8);
if (err < 0)
return err;
err = i2c_smbus_write_byte_data(client, reg & 0xff, value);
if (err < 0)
dev_err(&client->dev,
"Failed to write to register 0x%03x, err %d\n",
(int)reg, err);
return err;
} }
static struct w83795_data *w83795_update_device(struct device *dev) static struct w83795_data *w83795_update_device(struct device *dev)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment