diff options
author | Jean Delvare <khali@linux-fr.org> | 2010-10-28 14:31:45 -0400 |
---|---|---|
committer | Jean Delvare <khali@endymion.delvare> | 2010-10-28 14:31:45 -0400 |
commit | b2469f422f9ee2054359c4ec609c3bdb1f2d52f5 (patch) | |
tree | 2f7052c24378f144dc940f1095b3c408a61d1ba1 /drivers/hwmon/w83795.c | |
parent | 093d1a4794cc23dd221019eb1cdf42b16b48abcc (diff) |
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: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon/w83795.c')
-rw-r--r-- | drivers/hwmon/w83795.c | 93 |
1 files changed, 50 insertions, 43 deletions
diff --git a/drivers/hwmon/w83795.c b/drivers/hwmon/w83795.c index d7e1d3693a20..c7f6b1fd0899 100644 --- a/drivers/hwmon/w83795.c +++ b/drivers/hwmon/w83795.c | |||
@@ -360,60 +360,67 @@ struct w83795_data { | |||
360 | 360 | ||
361 | /* | 361 | /* |
362 | * Hardware access | 362 | * Hardware access |
363 | * We assume that nobdody can change the bank outside the driver. | ||
363 | */ | 364 | */ |
364 | 365 | ||
365 | /* Ignore the possibility that somebody change bank outside the driver | 366 | /* Must be called with data->update_lock held, except during initialization */ |
366 | * Must be called with data->update_lock held, except during initialization */ | 367 | static int w83795_set_bank(struct i2c_client *client, u8 bank) |
367 | static u8 w83795_read(struct i2c_client *client, u16 reg) | ||
368 | { | 368 | { |
369 | struct w83795_data *data = i2c_get_clientdata(client); | 369 | struct w83795_data *data = i2c_get_clientdata(client); |
370 | u8 res = 0xff; | 370 | int err; |
371 | u8 new_bank = reg >> 8; | 371 | |
372 | 372 | /* If the same bank is already set, nothing to do */ | |
373 | new_bank |= data->bank & 0xfc; | 373 | if ((data->bank & 0x07) == bank) |
374 | if (data->bank != new_bank) { | 374 | return 0; |
375 | if (i2c_smbus_write_byte_data | 375 | |
376 | (client, W83795_REG_BANKSEL, new_bank) >= 0) | 376 | /* Change to new bank, preserve all other bits */ |
377 | data->bank = new_bank; | 377 | bank |= data->bank & ~0x07; |
378 | else { | 378 | err = i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, bank); |
379 | dev_err(&client->dev, | 379 | if (err < 0) { |
380 | "set bank to %d failed, fall back " | 380 | dev_err(&client->dev, |
381 | "to bank %d, read reg 0x%x error\n", | 381 | "Failed to set bank to %d, err %d\n", |
382 | new_bank, data->bank, reg); | 382 | (int)bank, err); |
383 | res = 0x0; /* read 0x0 from the chip */ | 383 | return err; |
384 | goto END; | ||
385 | } | ||
386 | } | 384 | } |
387 | res = i2c_smbus_read_byte_data(client, reg & 0xff); | 385 | data->bank = bank; |
388 | END: | 386 | |
389 | return res; | 387 | return 0; |
390 | } | 388 | } |
391 | 389 | ||
392 | /* Must be called with data->update_lock held, except during initialization */ | 390 | /* Must be called with data->update_lock held, except during initialization */ |
393 | static int w83795_write(struct i2c_client *client, u16 reg, u8 value) | 391 | static u8 w83795_read(struct i2c_client *client, u16 reg) |
394 | { | 392 | { |
395 | struct w83795_data *data = i2c_get_clientdata(client); | 393 | int err; |
396 | int res; | 394 | |
397 | u8 new_bank = reg >> 8; | 395 | err = w83795_set_bank(client, reg >> 8); |
398 | 396 | if (err < 0) | |
399 | new_bank |= data->bank & 0xfc; | 397 | return 0x00; /* Arbitrary */ |
400 | if (data->bank != new_bank) { | 398 | |
401 | res = i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, | 399 | err = i2c_smbus_read_byte_data(client, reg & 0xff); |
402 | new_bank); | 400 | if (err < 0) { |
403 | if (res >= 0) | 401 | dev_err(&client->dev, |
404 | data->bank = new_bank; | 402 | "Failed to read from register 0x%03x, err %d\n", |
405 | else { | 403 | (int)reg, err); |
406 | dev_err(&client->dev, | 404 | return 0x00; /* Arbitrary */ |
407 | "set bank to %d failed, fall back " | ||
408 | "to bank %d, write reg 0x%x error\n", | ||
409 | new_bank, data->bank, reg); | ||
410 | goto END; | ||
411 | } | ||
412 | } | 405 | } |
406 | return err; | ||
407 | } | ||
413 | 408 | ||
414 | res = i2c_smbus_write_byte_data(client, reg & 0xff, value); | 409 | /* Must be called with data->update_lock held, except during initialization */ |
415 | END: | 410 | static int w83795_write(struct i2c_client *client, u16 reg, u8 value) |
416 | return res; | 411 | { |
412 | int err; | ||
413 | |||
414 | err = w83795_set_bank(client, reg >> 8); | ||
415 | if (err < 0) | ||
416 | return err; | ||
417 | |||
418 | err = i2c_smbus_write_byte_data(client, reg & 0xff, value); | ||
419 | if (err < 0) | ||
420 | dev_err(&client->dev, | ||
421 | "Failed to write to register 0x%03x, err %d\n", | ||
422 | (int)reg, err); | ||
423 | return err; | ||
417 | } | 424 | } |
418 | 425 | ||
419 | static struct w83795_data *w83795_update_device(struct device *dev) | 426 | static struct w83795_data *w83795_update_device(struct device *dev) |