Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+50 −43
Original line number Original line Diff line number Diff line
@@ -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)