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 /drivers/hwmon/lm90.c | |
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>
Diffstat (limited to 'drivers/hwmon/lm90.c')
-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 | ||