diff options
| author | Jean Delvare <khali@linux-fr.org> | 2008-10-17 11:51:09 -0400 |
|---|---|---|
| committer | Jean Delvare <khali@mahadeva.delvare> | 2008-10-17 11:51:09 -0400 |
| commit | 6388a388ffb720f40fc8046c261252ea2be9c12f (patch) | |
| tree | 1b5bcc83cd1fb6cac9fd222914545a43e1d7b3d4 | |
| parent | 2e532d68a2b3e2aa6b19731501222069735c741c (diff) | |
hwmon: (lm90) Move 16-bit value read to a separate function
Move the code which aggregates two 8-bit register values into a 16-bit
value to a separate function. We'll need to do it a second time soon and
I don't want to duplicate the code.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Acked-by: Martyn Welch <martyn.welch@gefanuc.com>
| -rw-r--r-- | drivers/hwmon/lm90.c | 72 |
1 files changed, 43 insertions, 29 deletions
diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index c24fe36ac787..73a1c622fb7a 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c | |||
| @@ -1,7 +1,7 @@ | |||
| 1 | /* | 1 | /* |
| 2 | * lm90.c - Part of lm_sensors, Linux kernel modules for hardware | 2 | * lm90.c - Part of lm_sensors, Linux kernel modules for hardware |
| 3 | * monitoring | 3 | * monitoring |
| 4 | * Copyright (C) 2003-2006 Jean Delvare <khali@linux-fr.org> | 4 | * Copyright (C) 2003-2008 Jean Delvare <khali@linux-fr.org> |
| 5 | * | 5 | * |
| 6 | * Based on the lm83 driver. The LM90 is a sensor chip made by National | 6 | * Based on the lm83 driver. The LM90 is a sensor chip made by National |
| 7 | * Semiconductor. It reports up to two temperatures (its own plus up to | 7 | * Semiconductor. It reports up to two temperatures (its own plus up to |
| @@ -736,6 +736,38 @@ static int lm90_remove(struct i2c_client *client) | |||
| 736 | return 0; | 736 | return 0; |
| 737 | } | 737 | } |
| 738 | 738 | ||
| 739 | static int lm90_read16(struct i2c_client *client, u8 regh, u8 regl, u16 *value) | ||
| 740 | { | ||
| 741 | int err; | ||
| 742 | u8 oldh, newh, l; | ||
| 743 | |||
| 744 | /* | ||
| 745 | * There is a trick here. We have to read two registers to have the | ||
| 746 | * sensor temperature, but we have to beware a conversion could occur | ||
| 747 | * inbetween the readings. The datasheet says we should either use | ||
| 748 | * the one-shot conversion register, which we don't want to do | ||
| 749 | * (disables hardware monitoring) or monitor the busy bit, which is | ||
| 750 | * impossible (we can't read the values and monitor that bit at the | ||
| 751 | * exact same time). So the solution used here is to read the high | ||
| 752 | * byte once, then the low byte, then the high byte again. If the new | ||
| 753 | * high byte matches the old one, then we have a valid reading. Else | ||
| 754 | * we have to read the low byte again, and now we believe we have a | ||
| 755 | * correct reading. | ||
| 756 | */ | ||
| 757 | if ((err = lm90_read_reg(client, regh, &oldh)) | ||
| 758 | || (err = lm90_read_reg(client, regl, &l)) | ||
| 759 | || (err = lm90_read_reg(client, regh, &newh))) | ||
| 760 | return err; | ||
| 761 | if (oldh != newh) { | ||
| 762 | err = lm90_read_reg(client, regl, &l); | ||
| 763 | if (err) | ||
| 764 | return err; | ||
| 765 | } | ||
| 766 | *value = (newh << 8) | l; | ||
| 767 | |||
| 768 | return 0; | ||
| 769 | } | ||
| 770 | |||
| 739 | static struct lm90_data *lm90_update_device(struct device *dev) | 771 | static struct lm90_data *lm90_update_device(struct device *dev) |
| 740 | { | 772 | { |
| 741 | struct i2c_client *client = to_i2c_client(dev); | 773 | struct i2c_client *client = to_i2c_client(dev); |
| @@ -744,7 +776,7 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
| 744 | mutex_lock(&data->update_lock); | 776 | mutex_lock(&data->update_lock); |
| 745 | 777 | ||
| 746 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { | 778 | if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) { |
| 747 | u8 oldh, newh, l; | 779 | u8 h, l; |
| 748 | 780 | ||
| 749 | dev_dbg(&client->dev, "Updating lm90 data.\n"); | 781 | dev_dbg(&client->dev, "Updating lm90 data.\n"); |
| 750 | lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]); | 782 | lm90_read_reg(client, LM90_REG_R_LOCAL_TEMP, &data->temp8[0]); |
| @@ -754,39 +786,21 @@ static struct lm90_data *lm90_update_device(struct device *dev) | |||
| 754 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]); | 786 | lm90_read_reg(client, LM90_REG_R_REMOTE_CRIT, &data->temp8[4]); |
| 755 | lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); | 787 | lm90_read_reg(client, LM90_REG_R_TCRIT_HYST, &data->temp_hyst); |
| 756 | 788 | ||
| 757 | /* | 789 | lm90_read16(client, LM90_REG_R_REMOTE_TEMPH, |
| 758 | * There is a trick here. We have to read two registers to | 790 | LM90_REG_R_REMOTE_TEMPL, &data->temp11[0]); |
| 759 | * have the remote sensor temperature, but we have to beware | 791 | |
| 760 | * a conversion could occur inbetween the readings. The | 792 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &h) == 0 |
| 761 | * datasheet says we should either use the one-shot | ||
| 762 | * conversion register, which we don't want to do (disables | ||
| 763 | * hardware monitoring) or monitor the busy bit, which is | ||
| 764 | * impossible (we can't read the values and monitor that bit | ||
| 765 | * at the exact same time). So the solution used here is to | ||
| 766 | * read the high byte once, then the low byte, then the high | ||
| 767 | * byte again. If the new high byte matches the old one, | ||
| 768 | * then we have a valid reading. Else we have to read the low | ||
| 769 | * byte again, and now we believe we have a correct reading. | ||
| 770 | */ | ||
| 771 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &oldh) == 0 | ||
| 772 | && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0 | ||
| 773 | && lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPH, &newh) == 0 | ||
| 774 | && (newh == oldh | ||
| 775 | || lm90_read_reg(client, LM90_REG_R_REMOTE_TEMPL, &l) == 0)) | ||
| 776 | data->temp11[0] = (newh << 8) | l; | ||
| 777 | |||
| 778 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_LOWH, &newh) == 0 | ||
| 779 | && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) | 793 | && lm90_read_reg(client, LM90_REG_R_REMOTE_LOWL, &l) == 0) |
| 780 | data->temp11[1] = (newh << 8) | l; | 794 | data->temp11[1] = (h << 8) | l; |
| 781 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &newh) == 0 | 795 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHH, &h) == 0 |
| 782 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) | 796 | && lm90_read_reg(client, LM90_REG_R_REMOTE_HIGHL, &l) == 0) |
| 783 | data->temp11[2] = (newh << 8) | l; | 797 | data->temp11[2] = (h << 8) | l; |
| 784 | if (data->kind != max6657) { | 798 | if (data->kind != max6657) { |
| 785 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, | 799 | if (lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSH, |
| 786 | &newh) == 0 | 800 | &h) == 0 |
| 787 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, | 801 | && lm90_read_reg(client, LM90_REG_R_REMOTE_OFFSL, |
| 788 | &l) == 0) | 802 | &l) == 0) |
| 789 | data->temp11[3] = (newh << 8) | l; | 803 | data->temp11[3] = (h << 8) | l; |
| 790 | } | 804 | } |
| 791 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); | 805 | lm90_read_reg(client, LM90_REG_R_STATUS, &data->alarms); |
| 792 | 806 | ||
