aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/w83795.c
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
commitb2469f422f9ee2054359c4ec609c3bdb1f2d52f5 (patch)
tree2f7052c24378f144dc940f1095b3c408a61d1ba1 /drivers/hwmon/w83795.c
parent093d1a4794cc23dd221019eb1cdf42b16b48abcc (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.c93
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 */ 367static int w83795_set_bank(struct i2c_client *client, u8 bank)
367static 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;
388END: 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 */
393static int w83795_write(struct i2c_client *client, u16 reg, u8 value) 391static 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 */
415END: 410static 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
419static struct w83795_data *w83795_update_device(struct device *dev) 426static struct w83795_data *w83795_update_device(struct device *dev)