diff options
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/w83l786ng.c | 209 |
1 files changed, 100 insertions, 109 deletions
diff --git a/drivers/hwmon/w83l786ng.c b/drivers/hwmon/w83l786ng.c index 32487c19cbfc..6caf33a5508b 100644 --- a/drivers/hwmon/w83l786ng.c +++ b/drivers/hwmon/w83l786ng.c | |||
@@ -148,32 +148,6 @@ struct w83l786ng_data { | |||
148 | u8 tolerance[2]; | 148 | u8 tolerance[2]; |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static int w83l786ng_probe(struct i2c_client *client, | ||
152 | const struct i2c_device_id *id); | ||
153 | static int w83l786ng_detect(struct i2c_client *client, | ||
154 | struct i2c_board_info *info); | ||
155 | static int w83l786ng_remove(struct i2c_client *client); | ||
156 | static void w83l786ng_init_client(struct i2c_client *client); | ||
157 | static struct w83l786ng_data *w83l786ng_update_device(struct device *dev); | ||
158 | |||
159 | static const struct i2c_device_id w83l786ng_id[] = { | ||
160 | { "w83l786ng", 0 }, | ||
161 | { } | ||
162 | }; | ||
163 | MODULE_DEVICE_TABLE(i2c, w83l786ng_id); | ||
164 | |||
165 | static struct i2c_driver w83l786ng_driver = { | ||
166 | .class = I2C_CLASS_HWMON, | ||
167 | .driver = { | ||
168 | .name = "w83l786ng", | ||
169 | }, | ||
170 | .probe = w83l786ng_probe, | ||
171 | .remove = w83l786ng_remove, | ||
172 | .id_table = w83l786ng_id, | ||
173 | .detect = w83l786ng_detect, | ||
174 | .address_list = normal_i2c, | ||
175 | }; | ||
176 | |||
177 | static u8 | 151 | static u8 |
178 | w83l786ng_read_value(struct i2c_client *client, u8 reg) | 152 | w83l786ng_read_value(struct i2c_client *client, u8 reg) |
179 | { | 153 | { |
@@ -186,6 +160,77 @@ w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value) | |||
186 | return i2c_smbus_write_byte_data(client, reg, value); | 160 | return i2c_smbus_write_byte_data(client, reg, value); |
187 | } | 161 | } |
188 | 162 | ||
163 | static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) | ||
164 | { | ||
165 | struct i2c_client *client = to_i2c_client(dev); | ||
166 | struct w83l786ng_data *data = i2c_get_clientdata(client); | ||
167 | int i, j; | ||
168 | u8 reg_tmp, pwmcfg; | ||
169 | |||
170 | mutex_lock(&data->update_lock); | ||
171 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
172 | || !data->valid) { | ||
173 | dev_dbg(&client->dev, "Updating w83l786ng data.\n"); | ||
174 | |||
175 | /* Update the voltages measured value and limits */ | ||
176 | for (i = 0; i < 3; i++) { | ||
177 | data->in[i] = w83l786ng_read_value(client, | ||
178 | W83L786NG_REG_IN(i)); | ||
179 | data->in_min[i] = w83l786ng_read_value(client, | ||
180 | W83L786NG_REG_IN_MIN(i)); | ||
181 | data->in_max[i] = w83l786ng_read_value(client, | ||
182 | W83L786NG_REG_IN_MAX(i)); | ||
183 | } | ||
184 | |||
185 | /* Update the fan counts and limits */ | ||
186 | for (i = 0; i < 2; i++) { | ||
187 | data->fan[i] = w83l786ng_read_value(client, | ||
188 | W83L786NG_REG_FAN(i)); | ||
189 | data->fan_min[i] = w83l786ng_read_value(client, | ||
190 | W83L786NG_REG_FAN_MIN(i)); | ||
191 | } | ||
192 | |||
193 | /* Update the fan divisor */ | ||
194 | reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV); | ||
195 | data->fan_div[0] = reg_tmp & 0x07; | ||
196 | data->fan_div[1] = (reg_tmp >> 4) & 0x07; | ||
197 | |||
198 | pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); | ||
199 | for (i = 0; i < 2; i++) { | ||
200 | data->pwm_mode[i] = | ||
201 | ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1) | ||
202 | ? 0 : 1; | ||
203 | data->pwm_enable[i] = | ||
204 | ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1; | ||
205 | data->pwm[i] = | ||
206 | (w83l786ng_read_value(client, W83L786NG_REG_PWM[i]) | ||
207 | & 0x0f) * 0x11; | ||
208 | } | ||
209 | |||
210 | |||
211 | /* Update the temperature sensors */ | ||
212 | for (i = 0; i < 2; i++) { | ||
213 | for (j = 0; j < 3; j++) { | ||
214 | data->temp[i][j] = w83l786ng_read_value(client, | ||
215 | W83L786NG_REG_TEMP[i][j]); | ||
216 | } | ||
217 | } | ||
218 | |||
219 | /* Update Smart Fan I/II tolerance */ | ||
220 | reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE); | ||
221 | data->tolerance[0] = reg_tmp & 0x0f; | ||
222 | data->tolerance[1] = (reg_tmp >> 4) & 0x0f; | ||
223 | |||
224 | data->last_updated = jiffies; | ||
225 | data->valid = 1; | ||
226 | |||
227 | } | ||
228 | |||
229 | mutex_unlock(&data->update_lock); | ||
230 | |||
231 | return data; | ||
232 | } | ||
233 | |||
189 | /* following are the sysfs callback functions */ | 234 | /* following are the sysfs callback functions */ |
190 | #define show_in_reg(reg) \ | 235 | #define show_in_reg(reg) \ |
191 | static ssize_t \ | 236 | static ssize_t \ |
@@ -662,6 +707,19 @@ w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info) | |||
662 | return 0; | 707 | return 0; |
663 | } | 708 | } |
664 | 709 | ||
710 | static void w83l786ng_init_client(struct i2c_client *client) | ||
711 | { | ||
712 | u8 tmp; | ||
713 | |||
714 | if (reset) | ||
715 | w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80); | ||
716 | |||
717 | /* Start monitoring */ | ||
718 | tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG); | ||
719 | if (!(tmp & 0x01)) | ||
720 | w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01); | ||
721 | } | ||
722 | |||
665 | static int | 723 | static int |
666 | w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id) | 724 | w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id) |
667 | { | 725 | { |
@@ -723,90 +781,23 @@ w83l786ng_remove(struct i2c_client *client) | |||
723 | return 0; | 781 | return 0; |
724 | } | 782 | } |
725 | 783 | ||
726 | static void | 784 | static const struct i2c_device_id w83l786ng_id[] = { |
727 | w83l786ng_init_client(struct i2c_client *client) | 785 | { "w83l786ng", 0 }, |
728 | { | 786 | { } |
729 | u8 tmp; | 787 | }; |
730 | 788 | MODULE_DEVICE_TABLE(i2c, w83l786ng_id); | |
731 | if (reset) | ||
732 | w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80); | ||
733 | |||
734 | /* Start monitoring */ | ||
735 | tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG); | ||
736 | if (!(tmp & 0x01)) | ||
737 | w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01); | ||
738 | } | ||
739 | |||
740 | static struct w83l786ng_data *w83l786ng_update_device(struct device *dev) | ||
741 | { | ||
742 | struct i2c_client *client = to_i2c_client(dev); | ||
743 | struct w83l786ng_data *data = i2c_get_clientdata(client); | ||
744 | int i, j; | ||
745 | u8 reg_tmp, pwmcfg; | ||
746 | |||
747 | mutex_lock(&data->update_lock); | ||
748 | if (time_after(jiffies, data->last_updated + HZ + HZ / 2) | ||
749 | || !data->valid) { | ||
750 | dev_dbg(&client->dev, "Updating w83l786ng data.\n"); | ||
751 | |||
752 | /* Update the voltages measured value and limits */ | ||
753 | for (i = 0; i < 3; i++) { | ||
754 | data->in[i] = w83l786ng_read_value(client, | ||
755 | W83L786NG_REG_IN(i)); | ||
756 | data->in_min[i] = w83l786ng_read_value(client, | ||
757 | W83L786NG_REG_IN_MIN(i)); | ||
758 | data->in_max[i] = w83l786ng_read_value(client, | ||
759 | W83L786NG_REG_IN_MAX(i)); | ||
760 | } | ||
761 | |||
762 | /* Update the fan counts and limits */ | ||
763 | for (i = 0; i < 2; i++) { | ||
764 | data->fan[i] = w83l786ng_read_value(client, | ||
765 | W83L786NG_REG_FAN(i)); | ||
766 | data->fan_min[i] = w83l786ng_read_value(client, | ||
767 | W83L786NG_REG_FAN_MIN(i)); | ||
768 | } | ||
769 | |||
770 | /* Update the fan divisor */ | ||
771 | reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV); | ||
772 | data->fan_div[0] = reg_tmp & 0x07; | ||
773 | data->fan_div[1] = (reg_tmp >> 4) & 0x07; | ||
774 | |||
775 | pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG); | ||
776 | for (i = 0; i < 2; i++) { | ||
777 | data->pwm_mode[i] = | ||
778 | ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1) | ||
779 | ? 0 : 1; | ||
780 | data->pwm_enable[i] = | ||
781 | ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1; | ||
782 | data->pwm[i] = | ||
783 | (w83l786ng_read_value(client, W83L786NG_REG_PWM[i]) | ||
784 | & 0x0f) * 0x11; | ||
785 | } | ||
786 | |||
787 | |||
788 | /* Update the temperature sensors */ | ||
789 | for (i = 0; i < 2; i++) { | ||
790 | for (j = 0; j < 3; j++) { | ||
791 | data->temp[i][j] = w83l786ng_read_value(client, | ||
792 | W83L786NG_REG_TEMP[i][j]); | ||
793 | } | ||
794 | } | ||
795 | |||
796 | /* Update Smart Fan I/II tolerance */ | ||
797 | reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE); | ||
798 | data->tolerance[0] = reg_tmp & 0x0f; | ||
799 | data->tolerance[1] = (reg_tmp >> 4) & 0x0f; | ||
800 | |||
801 | data->last_updated = jiffies; | ||
802 | data->valid = 1; | ||
803 | |||
804 | } | ||
805 | |||
806 | mutex_unlock(&data->update_lock); | ||
807 | 789 | ||
808 | return data; | 790 | static struct i2c_driver w83l786ng_driver = { |
809 | } | 791 | .class = I2C_CLASS_HWMON, |
792 | .driver = { | ||
793 | .name = "w83l786ng", | ||
794 | }, | ||
795 | .probe = w83l786ng_probe, | ||
796 | .remove = w83l786ng_remove, | ||
797 | .id_table = w83l786ng_id, | ||
798 | .detect = w83l786ng_detect, | ||
799 | .address_list = normal_i2c, | ||
800 | }; | ||
810 | 801 | ||
811 | module_i2c_driver(w83l786ng_driver); | 802 | module_i2c_driver(w83l786ng_driver); |
812 | 803 | ||