Commit 0657777fcefffbf79d4a5fa0952a3f1a4248c0da
Committed by
Jean Delvare
1 parent
fa845740cb
Exists in
smarc-l5.0.0_1.0.0-ga
and in
5 other branches
hwmon: Drop needless includes of <linux/delay.h>
These drivers use no sleep or delay functions so they don't need to include <linux/delay.h>. Signed-off-by: Jean Delvare <khali@linux-fr.org> Acked-by: Guenter Roeck <linux@roeck-us.net> Cc: Rudolf Marek <r.marek@assembler.cz>
Showing 10 changed files with 0 additions and 10 deletions Inline Diff
drivers/hwmon/adt7411.c
1 | /* | 1 | /* |
2 | * Driver for the ADT7411 (I2C/SPI 8 channel 10 bit ADC & temperature-sensor) | 2 | * Driver for the ADT7411 (I2C/SPI 8 channel 10 bit ADC & temperature-sensor) |
3 | * | 3 | * |
4 | * Copyright (C) 2008, 2010 Pengutronix | 4 | * Copyright (C) 2008, 2010 Pengutronix |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 7 | * it under the terms of the GNU General Public License version 2 as |
8 | * published by the Free Software Foundation. | 8 | * published by the Free Software Foundation. |
9 | * | 9 | * |
10 | * TODO: SPI, support for external temperature sensor | 10 | * TODO: SPI, support for external temperature sensor |
11 | * use power-down mode for suspend?, interrupt handling? | 11 | * use power-down mode for suspend?, interrupt handling? |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/init.h> | 16 | #include <linux/init.h> |
17 | #include <linux/err.h> | 17 | #include <linux/err.h> |
18 | #include <linux/delay.h> | ||
19 | #include <linux/mutex.h> | 18 | #include <linux/mutex.h> |
20 | #include <linux/jiffies.h> | 19 | #include <linux/jiffies.h> |
21 | #include <linux/i2c.h> | 20 | #include <linux/i2c.h> |
22 | #include <linux/hwmon.h> | 21 | #include <linux/hwmon.h> |
23 | #include <linux/hwmon-sysfs.h> | 22 | #include <linux/hwmon-sysfs.h> |
24 | #include <linux/slab.h> | 23 | #include <linux/slab.h> |
25 | 24 | ||
26 | #define ADT7411_REG_INT_TEMP_VDD_LSB 0x03 | 25 | #define ADT7411_REG_INT_TEMP_VDD_LSB 0x03 |
27 | #define ADT7411_REG_EXT_TEMP_AIN14_LSB 0x04 | 26 | #define ADT7411_REG_EXT_TEMP_AIN14_LSB 0x04 |
28 | #define ADT7411_REG_VDD_MSB 0x06 | 27 | #define ADT7411_REG_VDD_MSB 0x06 |
29 | #define ADT7411_REG_INT_TEMP_MSB 0x07 | 28 | #define ADT7411_REG_INT_TEMP_MSB 0x07 |
30 | #define ADT7411_REG_EXT_TEMP_AIN1_MSB 0x08 | 29 | #define ADT7411_REG_EXT_TEMP_AIN1_MSB 0x08 |
31 | 30 | ||
32 | #define ADT7411_REG_CFG1 0x18 | 31 | #define ADT7411_REG_CFG1 0x18 |
33 | #define ADT7411_CFG1_START_MONITOR (1 << 0) | 32 | #define ADT7411_CFG1_START_MONITOR (1 << 0) |
34 | 33 | ||
35 | #define ADT7411_REG_CFG2 0x19 | 34 | #define ADT7411_REG_CFG2 0x19 |
36 | #define ADT7411_CFG2_DISABLE_AVG (1 << 5) | 35 | #define ADT7411_CFG2_DISABLE_AVG (1 << 5) |
37 | 36 | ||
38 | #define ADT7411_REG_CFG3 0x1a | 37 | #define ADT7411_REG_CFG3 0x1a |
39 | #define ADT7411_CFG3_ADC_CLK_225 (1 << 0) | 38 | #define ADT7411_CFG3_ADC_CLK_225 (1 << 0) |
40 | #define ADT7411_CFG3_REF_VDD (1 << 4) | 39 | #define ADT7411_CFG3_REF_VDD (1 << 4) |
41 | 40 | ||
42 | #define ADT7411_REG_DEVICE_ID 0x4d | 41 | #define ADT7411_REG_DEVICE_ID 0x4d |
43 | #define ADT7411_REG_MANUFACTURER_ID 0x4e | 42 | #define ADT7411_REG_MANUFACTURER_ID 0x4e |
44 | 43 | ||
45 | #define ADT7411_DEVICE_ID 0x2 | 44 | #define ADT7411_DEVICE_ID 0x2 |
46 | #define ADT7411_MANUFACTURER_ID 0x41 | 45 | #define ADT7411_MANUFACTURER_ID 0x41 |
47 | 46 | ||
48 | static const unsigned short normal_i2c[] = { 0x48, 0x4a, 0x4b, I2C_CLIENT_END }; | 47 | static const unsigned short normal_i2c[] = { 0x48, 0x4a, 0x4b, I2C_CLIENT_END }; |
49 | 48 | ||
50 | struct adt7411_data { | 49 | struct adt7411_data { |
51 | struct mutex device_lock; /* for "atomic" device accesses */ | 50 | struct mutex device_lock; /* for "atomic" device accesses */ |
52 | struct mutex update_lock; | 51 | struct mutex update_lock; |
53 | unsigned long next_update; | 52 | unsigned long next_update; |
54 | int vref_cached; | 53 | int vref_cached; |
55 | struct device *hwmon_dev; | 54 | struct device *hwmon_dev; |
56 | }; | 55 | }; |
57 | 56 | ||
58 | /* | 57 | /* |
59 | * When reading a register containing (up to 4) lsb, all associated | 58 | * When reading a register containing (up to 4) lsb, all associated |
60 | * msb-registers get locked by the hardware. After _one_ of those msb is read, | 59 | * msb-registers get locked by the hardware. After _one_ of those msb is read, |
61 | * _all_ are unlocked. In order to use this locking correctly, reading lsb/msb | 60 | * _all_ are unlocked. In order to use this locking correctly, reading lsb/msb |
62 | * is protected here with a mutex, too. | 61 | * is protected here with a mutex, too. |
63 | */ | 62 | */ |
64 | static int adt7411_read_10_bit(struct i2c_client *client, u8 lsb_reg, | 63 | static int adt7411_read_10_bit(struct i2c_client *client, u8 lsb_reg, |
65 | u8 msb_reg, u8 lsb_shift) | 64 | u8 msb_reg, u8 lsb_shift) |
66 | { | 65 | { |
67 | struct adt7411_data *data = i2c_get_clientdata(client); | 66 | struct adt7411_data *data = i2c_get_clientdata(client); |
68 | int val, tmp; | 67 | int val, tmp; |
69 | 68 | ||
70 | mutex_lock(&data->device_lock); | 69 | mutex_lock(&data->device_lock); |
71 | 70 | ||
72 | val = i2c_smbus_read_byte_data(client, lsb_reg); | 71 | val = i2c_smbus_read_byte_data(client, lsb_reg); |
73 | if (val < 0) | 72 | if (val < 0) |
74 | goto exit_unlock; | 73 | goto exit_unlock; |
75 | 74 | ||
76 | tmp = (val >> lsb_shift) & 3; | 75 | tmp = (val >> lsb_shift) & 3; |
77 | val = i2c_smbus_read_byte_data(client, msb_reg); | 76 | val = i2c_smbus_read_byte_data(client, msb_reg); |
78 | 77 | ||
79 | if (val >= 0) | 78 | if (val >= 0) |
80 | val = (val << 2) | tmp; | 79 | val = (val << 2) | tmp; |
81 | 80 | ||
82 | exit_unlock: | 81 | exit_unlock: |
83 | mutex_unlock(&data->device_lock); | 82 | mutex_unlock(&data->device_lock); |
84 | 83 | ||
85 | return val; | 84 | return val; |
86 | } | 85 | } |
87 | 86 | ||
88 | static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit, | 87 | static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit, |
89 | bool flag) | 88 | bool flag) |
90 | { | 89 | { |
91 | struct adt7411_data *data = i2c_get_clientdata(client); | 90 | struct adt7411_data *data = i2c_get_clientdata(client); |
92 | int ret, val; | 91 | int ret, val; |
93 | 92 | ||
94 | mutex_lock(&data->device_lock); | 93 | mutex_lock(&data->device_lock); |
95 | 94 | ||
96 | ret = i2c_smbus_read_byte_data(client, reg); | 95 | ret = i2c_smbus_read_byte_data(client, reg); |
97 | if (ret < 0) | 96 | if (ret < 0) |
98 | goto exit_unlock; | 97 | goto exit_unlock; |
99 | 98 | ||
100 | if (flag) | 99 | if (flag) |
101 | val = ret | bit; | 100 | val = ret | bit; |
102 | else | 101 | else |
103 | val = ret & ~bit; | 102 | val = ret & ~bit; |
104 | 103 | ||
105 | ret = i2c_smbus_write_byte_data(client, reg, val); | 104 | ret = i2c_smbus_write_byte_data(client, reg, val); |
106 | 105 | ||
107 | exit_unlock: | 106 | exit_unlock: |
108 | mutex_unlock(&data->device_lock); | 107 | mutex_unlock(&data->device_lock); |
109 | return ret; | 108 | return ret; |
110 | } | 109 | } |
111 | 110 | ||
112 | static ssize_t adt7411_show_vdd(struct device *dev, | 111 | static ssize_t adt7411_show_vdd(struct device *dev, |
113 | struct device_attribute *attr, char *buf) | 112 | struct device_attribute *attr, char *buf) |
114 | { | 113 | { |
115 | struct i2c_client *client = to_i2c_client(dev); | 114 | struct i2c_client *client = to_i2c_client(dev); |
116 | int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB, | 115 | int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB, |
117 | ADT7411_REG_VDD_MSB, 2); | 116 | ADT7411_REG_VDD_MSB, 2); |
118 | 117 | ||
119 | return ret < 0 ? ret : sprintf(buf, "%u\n", ret * 7000 / 1024); | 118 | return ret < 0 ? ret : sprintf(buf, "%u\n", ret * 7000 / 1024); |
120 | } | 119 | } |
121 | 120 | ||
122 | static ssize_t adt7411_show_temp(struct device *dev, | 121 | static ssize_t adt7411_show_temp(struct device *dev, |
123 | struct device_attribute *attr, char *buf) | 122 | struct device_attribute *attr, char *buf) |
124 | { | 123 | { |
125 | struct i2c_client *client = to_i2c_client(dev); | 124 | struct i2c_client *client = to_i2c_client(dev); |
126 | int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB, | 125 | int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB, |
127 | ADT7411_REG_INT_TEMP_MSB, 0); | 126 | ADT7411_REG_INT_TEMP_MSB, 0); |
128 | 127 | ||
129 | if (val < 0) | 128 | if (val < 0) |
130 | return val; | 129 | return val; |
131 | 130 | ||
132 | val = val & 0x200 ? val - 0x400 : val; /* 10 bit signed */ | 131 | val = val & 0x200 ? val - 0x400 : val; /* 10 bit signed */ |
133 | 132 | ||
134 | return sprintf(buf, "%d\n", val * 250); | 133 | return sprintf(buf, "%d\n", val * 250); |
135 | } | 134 | } |
136 | 135 | ||
137 | static ssize_t adt7411_show_input(struct device *dev, | 136 | static ssize_t adt7411_show_input(struct device *dev, |
138 | struct device_attribute *attr, char *buf) | 137 | struct device_attribute *attr, char *buf) |
139 | { | 138 | { |
140 | int nr = to_sensor_dev_attr(attr)->index; | 139 | int nr = to_sensor_dev_attr(attr)->index; |
141 | struct i2c_client *client = to_i2c_client(dev); | 140 | struct i2c_client *client = to_i2c_client(dev); |
142 | struct adt7411_data *data = i2c_get_clientdata(client); | 141 | struct adt7411_data *data = i2c_get_clientdata(client); |
143 | int val; | 142 | int val; |
144 | u8 lsb_reg, lsb_shift; | 143 | u8 lsb_reg, lsb_shift; |
145 | 144 | ||
146 | mutex_lock(&data->update_lock); | 145 | mutex_lock(&data->update_lock); |
147 | if (time_after_eq(jiffies, data->next_update)) { | 146 | if (time_after_eq(jiffies, data->next_update)) { |
148 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3); | 147 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_CFG3); |
149 | if (val < 0) | 148 | if (val < 0) |
150 | goto exit_unlock; | 149 | goto exit_unlock; |
151 | 150 | ||
152 | if (val & ADT7411_CFG3_REF_VDD) { | 151 | if (val & ADT7411_CFG3_REF_VDD) { |
153 | val = adt7411_read_10_bit(client, | 152 | val = adt7411_read_10_bit(client, |
154 | ADT7411_REG_INT_TEMP_VDD_LSB, | 153 | ADT7411_REG_INT_TEMP_VDD_LSB, |
155 | ADT7411_REG_VDD_MSB, 2); | 154 | ADT7411_REG_VDD_MSB, 2); |
156 | if (val < 0) | 155 | if (val < 0) |
157 | goto exit_unlock; | 156 | goto exit_unlock; |
158 | 157 | ||
159 | data->vref_cached = val * 7000 / 1024; | 158 | data->vref_cached = val * 7000 / 1024; |
160 | } else { | 159 | } else { |
161 | data->vref_cached = 2250; | 160 | data->vref_cached = 2250; |
162 | } | 161 | } |
163 | 162 | ||
164 | data->next_update = jiffies + HZ; | 163 | data->next_update = jiffies + HZ; |
165 | } | 164 | } |
166 | 165 | ||
167 | lsb_reg = ADT7411_REG_EXT_TEMP_AIN14_LSB + (nr >> 2); | 166 | lsb_reg = ADT7411_REG_EXT_TEMP_AIN14_LSB + (nr >> 2); |
168 | lsb_shift = 2 * (nr & 0x03); | 167 | lsb_shift = 2 * (nr & 0x03); |
169 | val = adt7411_read_10_bit(client, lsb_reg, | 168 | val = adt7411_read_10_bit(client, lsb_reg, |
170 | ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, lsb_shift); | 169 | ADT7411_REG_EXT_TEMP_AIN1_MSB + nr, lsb_shift); |
171 | if (val < 0) | 170 | if (val < 0) |
172 | goto exit_unlock; | 171 | goto exit_unlock; |
173 | 172 | ||
174 | val = sprintf(buf, "%u\n", val * data->vref_cached / 1024); | 173 | val = sprintf(buf, "%u\n", val * data->vref_cached / 1024); |
175 | exit_unlock: | 174 | exit_unlock: |
176 | mutex_unlock(&data->update_lock); | 175 | mutex_unlock(&data->update_lock); |
177 | return val; | 176 | return val; |
178 | } | 177 | } |
179 | 178 | ||
180 | static ssize_t adt7411_show_bit(struct device *dev, | 179 | static ssize_t adt7411_show_bit(struct device *dev, |
181 | struct device_attribute *attr, char *buf) | 180 | struct device_attribute *attr, char *buf) |
182 | { | 181 | { |
183 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); | 182 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr); |
184 | struct i2c_client *client = to_i2c_client(dev); | 183 | struct i2c_client *client = to_i2c_client(dev); |
185 | int ret = i2c_smbus_read_byte_data(client, attr2->index); | 184 | int ret = i2c_smbus_read_byte_data(client, attr2->index); |
186 | 185 | ||
187 | return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr)); | 186 | return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr)); |
188 | } | 187 | } |
189 | 188 | ||
190 | static ssize_t adt7411_set_bit(struct device *dev, | 189 | static ssize_t adt7411_set_bit(struct device *dev, |
191 | struct device_attribute *attr, const char *buf, | 190 | struct device_attribute *attr, const char *buf, |
192 | size_t count) | 191 | size_t count) |
193 | { | 192 | { |
194 | struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr); | 193 | struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr); |
195 | struct i2c_client *client = to_i2c_client(dev); | 194 | struct i2c_client *client = to_i2c_client(dev); |
196 | struct adt7411_data *data = i2c_get_clientdata(client); | 195 | struct adt7411_data *data = i2c_get_clientdata(client); |
197 | int ret; | 196 | int ret; |
198 | unsigned long flag; | 197 | unsigned long flag; |
199 | 198 | ||
200 | ret = kstrtoul(buf, 0, &flag); | 199 | ret = kstrtoul(buf, 0, &flag); |
201 | if (ret || flag > 1) | 200 | if (ret || flag > 1) |
202 | return -EINVAL; | 201 | return -EINVAL; |
203 | 202 | ||
204 | ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag); | 203 | ret = adt7411_modify_bit(client, s_attr2->index, s_attr2->nr, flag); |
205 | 204 | ||
206 | /* force update */ | 205 | /* force update */ |
207 | mutex_lock(&data->update_lock); | 206 | mutex_lock(&data->update_lock); |
208 | data->next_update = jiffies; | 207 | data->next_update = jiffies; |
209 | mutex_unlock(&data->update_lock); | 208 | mutex_unlock(&data->update_lock); |
210 | 209 | ||
211 | return ret < 0 ? ret : count; | 210 | return ret < 0 ? ret : count; |
212 | } | 211 | } |
213 | 212 | ||
214 | #define ADT7411_BIT_ATTR(__name, __reg, __bit) \ | 213 | #define ADT7411_BIT_ATTR(__name, __reg, __bit) \ |
215 | SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \ | 214 | SENSOR_DEVICE_ATTR_2(__name, S_IRUGO | S_IWUSR, adt7411_show_bit, \ |
216 | adt7411_set_bit, __bit, __reg) | 215 | adt7411_set_bit, __bit, __reg) |
217 | 216 | ||
218 | static DEVICE_ATTR(temp1_input, S_IRUGO, adt7411_show_temp, NULL); | 217 | static DEVICE_ATTR(temp1_input, S_IRUGO, adt7411_show_temp, NULL); |
219 | static DEVICE_ATTR(in0_input, S_IRUGO, adt7411_show_vdd, NULL); | 218 | static DEVICE_ATTR(in0_input, S_IRUGO, adt7411_show_vdd, NULL); |
220 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, adt7411_show_input, NULL, 0); | 219 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, adt7411_show_input, NULL, 0); |
221 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, adt7411_show_input, NULL, 1); | 220 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, adt7411_show_input, NULL, 1); |
222 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, adt7411_show_input, NULL, 2); | 221 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, adt7411_show_input, NULL, 2); |
223 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, adt7411_show_input, NULL, 3); | 222 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, adt7411_show_input, NULL, 3); |
224 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, adt7411_show_input, NULL, 4); | 223 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, adt7411_show_input, NULL, 4); |
225 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, adt7411_show_input, NULL, 5); | 224 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, adt7411_show_input, NULL, 5); |
226 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, adt7411_show_input, NULL, 6); | 225 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, adt7411_show_input, NULL, 6); |
227 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, adt7411_show_input, NULL, 7); | 226 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, adt7411_show_input, NULL, 7); |
228 | static ADT7411_BIT_ATTR(no_average, ADT7411_REG_CFG2, ADT7411_CFG2_DISABLE_AVG); | 227 | static ADT7411_BIT_ATTR(no_average, ADT7411_REG_CFG2, ADT7411_CFG2_DISABLE_AVG); |
229 | static ADT7411_BIT_ATTR(fast_sampling, ADT7411_REG_CFG3, ADT7411_CFG3_ADC_CLK_225); | 228 | static ADT7411_BIT_ATTR(fast_sampling, ADT7411_REG_CFG3, ADT7411_CFG3_ADC_CLK_225); |
230 | static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD); | 229 | static ADT7411_BIT_ATTR(adc_ref_vdd, ADT7411_REG_CFG3, ADT7411_CFG3_REF_VDD); |
231 | 230 | ||
232 | static struct attribute *adt7411_attrs[] = { | 231 | static struct attribute *adt7411_attrs[] = { |
233 | &dev_attr_temp1_input.attr, | 232 | &dev_attr_temp1_input.attr, |
234 | &dev_attr_in0_input.attr, | 233 | &dev_attr_in0_input.attr, |
235 | &sensor_dev_attr_in1_input.dev_attr.attr, | 234 | &sensor_dev_attr_in1_input.dev_attr.attr, |
236 | &sensor_dev_attr_in2_input.dev_attr.attr, | 235 | &sensor_dev_attr_in2_input.dev_attr.attr, |
237 | &sensor_dev_attr_in3_input.dev_attr.attr, | 236 | &sensor_dev_attr_in3_input.dev_attr.attr, |
238 | &sensor_dev_attr_in4_input.dev_attr.attr, | 237 | &sensor_dev_attr_in4_input.dev_attr.attr, |
239 | &sensor_dev_attr_in5_input.dev_attr.attr, | 238 | &sensor_dev_attr_in5_input.dev_attr.attr, |
240 | &sensor_dev_attr_in6_input.dev_attr.attr, | 239 | &sensor_dev_attr_in6_input.dev_attr.attr, |
241 | &sensor_dev_attr_in7_input.dev_attr.attr, | 240 | &sensor_dev_attr_in7_input.dev_attr.attr, |
242 | &sensor_dev_attr_in8_input.dev_attr.attr, | 241 | &sensor_dev_attr_in8_input.dev_attr.attr, |
243 | &sensor_dev_attr_no_average.dev_attr.attr, | 242 | &sensor_dev_attr_no_average.dev_attr.attr, |
244 | &sensor_dev_attr_fast_sampling.dev_attr.attr, | 243 | &sensor_dev_attr_fast_sampling.dev_attr.attr, |
245 | &sensor_dev_attr_adc_ref_vdd.dev_attr.attr, | 244 | &sensor_dev_attr_adc_ref_vdd.dev_attr.attr, |
246 | NULL | 245 | NULL |
247 | }; | 246 | }; |
248 | 247 | ||
249 | static const struct attribute_group adt7411_attr_grp = { | 248 | static const struct attribute_group adt7411_attr_grp = { |
250 | .attrs = adt7411_attrs, | 249 | .attrs = adt7411_attrs, |
251 | }; | 250 | }; |
252 | 251 | ||
253 | static int adt7411_detect(struct i2c_client *client, | 252 | static int adt7411_detect(struct i2c_client *client, |
254 | struct i2c_board_info *info) | 253 | struct i2c_board_info *info) |
255 | { | 254 | { |
256 | int val; | 255 | int val; |
257 | 256 | ||
258 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 257 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
259 | return -ENODEV; | 258 | return -ENODEV; |
260 | 259 | ||
261 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID); | 260 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_MANUFACTURER_ID); |
262 | if (val < 0 || val != ADT7411_MANUFACTURER_ID) { | 261 | if (val < 0 || val != ADT7411_MANUFACTURER_ID) { |
263 | dev_dbg(&client->dev, "Wrong manufacturer ID. Got %d, " | 262 | dev_dbg(&client->dev, "Wrong manufacturer ID. Got %d, " |
264 | "expected %d\n", val, ADT7411_MANUFACTURER_ID); | 263 | "expected %d\n", val, ADT7411_MANUFACTURER_ID); |
265 | return -ENODEV; | 264 | return -ENODEV; |
266 | } | 265 | } |
267 | 266 | ||
268 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID); | 267 | val = i2c_smbus_read_byte_data(client, ADT7411_REG_DEVICE_ID); |
269 | if (val < 0 || val != ADT7411_DEVICE_ID) { | 268 | if (val < 0 || val != ADT7411_DEVICE_ID) { |
270 | dev_dbg(&client->dev, "Wrong device ID. Got %d, " | 269 | dev_dbg(&client->dev, "Wrong device ID. Got %d, " |
271 | "expected %d\n", val, ADT7411_DEVICE_ID); | 270 | "expected %d\n", val, ADT7411_DEVICE_ID); |
272 | return -ENODEV; | 271 | return -ENODEV; |
273 | } | 272 | } |
274 | 273 | ||
275 | strlcpy(info->type, "adt7411", I2C_NAME_SIZE); | 274 | strlcpy(info->type, "adt7411", I2C_NAME_SIZE); |
276 | 275 | ||
277 | return 0; | 276 | return 0; |
278 | } | 277 | } |
279 | 278 | ||
280 | static int __devinit adt7411_probe(struct i2c_client *client, | 279 | static int __devinit adt7411_probe(struct i2c_client *client, |
281 | const struct i2c_device_id *id) | 280 | const struct i2c_device_id *id) |
282 | { | 281 | { |
283 | struct adt7411_data *data; | 282 | struct adt7411_data *data; |
284 | int ret; | 283 | int ret; |
285 | 284 | ||
286 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | 285 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); |
287 | if (!data) | 286 | if (!data) |
288 | return -ENOMEM; | 287 | return -ENOMEM; |
289 | 288 | ||
290 | i2c_set_clientdata(client, data); | 289 | i2c_set_clientdata(client, data); |
291 | mutex_init(&data->device_lock); | 290 | mutex_init(&data->device_lock); |
292 | mutex_init(&data->update_lock); | 291 | mutex_init(&data->update_lock); |
293 | 292 | ||
294 | ret = adt7411_modify_bit(client, ADT7411_REG_CFG1, | 293 | ret = adt7411_modify_bit(client, ADT7411_REG_CFG1, |
295 | ADT7411_CFG1_START_MONITOR, 1); | 294 | ADT7411_CFG1_START_MONITOR, 1); |
296 | if (ret < 0) | 295 | if (ret < 0) |
297 | return ret; | 296 | return ret; |
298 | 297 | ||
299 | /* force update on first occasion */ | 298 | /* force update on first occasion */ |
300 | data->next_update = jiffies; | 299 | data->next_update = jiffies; |
301 | 300 | ||
302 | ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp); | 301 | ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp); |
303 | if (ret) | 302 | if (ret) |
304 | return ret; | 303 | return ret; |
305 | 304 | ||
306 | data->hwmon_dev = hwmon_device_register(&client->dev); | 305 | data->hwmon_dev = hwmon_device_register(&client->dev); |
307 | if (IS_ERR(data->hwmon_dev)) { | 306 | if (IS_ERR(data->hwmon_dev)) { |
308 | ret = PTR_ERR(data->hwmon_dev); | 307 | ret = PTR_ERR(data->hwmon_dev); |
309 | goto exit_remove; | 308 | goto exit_remove; |
310 | } | 309 | } |
311 | 310 | ||
312 | dev_info(&client->dev, "successfully registered\n"); | 311 | dev_info(&client->dev, "successfully registered\n"); |
313 | 312 | ||
314 | return 0; | 313 | return 0; |
315 | 314 | ||
316 | exit_remove: | 315 | exit_remove: |
317 | sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); | 316 | sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); |
318 | return ret; | 317 | return ret; |
319 | } | 318 | } |
320 | 319 | ||
321 | static int __devexit adt7411_remove(struct i2c_client *client) | 320 | static int __devexit adt7411_remove(struct i2c_client *client) |
322 | { | 321 | { |
323 | struct adt7411_data *data = i2c_get_clientdata(client); | 322 | struct adt7411_data *data = i2c_get_clientdata(client); |
324 | 323 | ||
325 | hwmon_device_unregister(data->hwmon_dev); | 324 | hwmon_device_unregister(data->hwmon_dev); |
326 | sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); | 325 | sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp); |
327 | return 0; | 326 | return 0; |
328 | } | 327 | } |
329 | 328 | ||
330 | static const struct i2c_device_id adt7411_id[] = { | 329 | static const struct i2c_device_id adt7411_id[] = { |
331 | { "adt7411", 0 }, | 330 | { "adt7411", 0 }, |
332 | { } | 331 | { } |
333 | }; | 332 | }; |
334 | MODULE_DEVICE_TABLE(i2c, adt7411_id); | 333 | MODULE_DEVICE_TABLE(i2c, adt7411_id); |
335 | 334 | ||
336 | static struct i2c_driver adt7411_driver = { | 335 | static struct i2c_driver adt7411_driver = { |
337 | .driver = { | 336 | .driver = { |
338 | .name = "adt7411", | 337 | .name = "adt7411", |
339 | }, | 338 | }, |
340 | .probe = adt7411_probe, | 339 | .probe = adt7411_probe, |
341 | .remove = __devexit_p(adt7411_remove), | 340 | .remove = __devexit_p(adt7411_remove), |
342 | .id_table = adt7411_id, | 341 | .id_table = adt7411_id, |
343 | .detect = adt7411_detect, | 342 | .detect = adt7411_detect, |
344 | .address_list = normal_i2c, | 343 | .address_list = normal_i2c, |
345 | .class = I2C_CLASS_HWMON, | 344 | .class = I2C_CLASS_HWMON, |
346 | }; | 345 | }; |
347 | 346 | ||
348 | module_i2c_driver(adt7411_driver); | 347 | module_i2c_driver(adt7411_driver); |
349 | 348 | ||
350 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de> and " | 349 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de> and " |
351 | "Wolfram Sang <w.sang@pengutronix.de>"); | 350 | "Wolfram Sang <w.sang@pengutronix.de>"); |
352 | MODULE_DESCRIPTION("ADT7411 driver"); | 351 | MODULE_DESCRIPTION("ADT7411 driver"); |
353 | MODULE_LICENSE("GPL v2"); | 352 | MODULE_LICENSE("GPL v2"); |
354 | 353 |
drivers/hwmon/adt7462.c
1 | /* | 1 | /* |
2 | * A hwmon driver for the Analog Devices ADT7462 | 2 | * A hwmon driver for the Analog Devices ADT7462 |
3 | * Copyright (C) 2008 IBM | 3 | * Copyright (C) 2008 IBM |
4 | * | 4 | * |
5 | * Author: Darrick J. Wong <djwong@us.ibm.com> | 5 | * Author: Darrick J. Wong <djwong@us.ibm.com> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation; either version 2 of the License, or | 9 | * the Free Software Foundation; either version 2 of the License, or |
10 | * (at your option) any later version. | 10 | * (at your option) any later version. |
11 | * | 11 | * |
12 | * This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | * GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
16 | * | 16 | * |
17 | * You should have received a copy of the GNU General Public License | 17 | * You should have received a copy of the GNU General Public License |
18 | * along with this program; if not, write to the Free Software | 18 | * along with this program; if not, write to the Free Software |
19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
20 | */ | 20 | */ |
21 | 21 | ||
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/jiffies.h> | 23 | #include <linux/jiffies.h> |
24 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
25 | #include <linux/hwmon.h> | 25 | #include <linux/hwmon.h> |
26 | #include <linux/hwmon-sysfs.h> | 26 | #include <linux/hwmon-sysfs.h> |
27 | #include <linux/err.h> | 27 | #include <linux/err.h> |
28 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
29 | #include <linux/delay.h> | ||
30 | #include <linux/log2.h> | 29 | #include <linux/log2.h> |
31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
32 | 31 | ||
33 | /* Addresses to scan */ | 32 | /* Addresses to scan */ |
34 | static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; | 33 | static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END }; |
35 | 34 | ||
36 | /* ADT7462 registers */ | 35 | /* ADT7462 registers */ |
37 | #define ADT7462_REG_DEVICE 0x3D | 36 | #define ADT7462_REG_DEVICE 0x3D |
38 | #define ADT7462_REG_VENDOR 0x3E | 37 | #define ADT7462_REG_VENDOR 0x3E |
39 | #define ADT7462_REG_REVISION 0x3F | 38 | #define ADT7462_REG_REVISION 0x3F |
40 | 39 | ||
41 | #define ADT7462_REG_MIN_TEMP_BASE_ADDR 0x44 | 40 | #define ADT7462_REG_MIN_TEMP_BASE_ADDR 0x44 |
42 | #define ADT7462_REG_MIN_TEMP_MAX_ADDR 0x47 | 41 | #define ADT7462_REG_MIN_TEMP_MAX_ADDR 0x47 |
43 | #define ADT7462_REG_MAX_TEMP_BASE_ADDR 0x48 | 42 | #define ADT7462_REG_MAX_TEMP_BASE_ADDR 0x48 |
44 | #define ADT7462_REG_MAX_TEMP_MAX_ADDR 0x4B | 43 | #define ADT7462_REG_MAX_TEMP_MAX_ADDR 0x4B |
45 | #define ADT7462_REG_TEMP_BASE_ADDR 0x88 | 44 | #define ADT7462_REG_TEMP_BASE_ADDR 0x88 |
46 | #define ADT7462_REG_TEMP_MAX_ADDR 0x8F | 45 | #define ADT7462_REG_TEMP_MAX_ADDR 0x8F |
47 | 46 | ||
48 | #define ADT7462_REG_FAN_BASE_ADDR 0x98 | 47 | #define ADT7462_REG_FAN_BASE_ADDR 0x98 |
49 | #define ADT7462_REG_FAN_MAX_ADDR 0x9F | 48 | #define ADT7462_REG_FAN_MAX_ADDR 0x9F |
50 | #define ADT7462_REG_FAN2_BASE_ADDR 0xA2 | 49 | #define ADT7462_REG_FAN2_BASE_ADDR 0xA2 |
51 | #define ADT7462_REG_FAN2_MAX_ADDR 0xA9 | 50 | #define ADT7462_REG_FAN2_MAX_ADDR 0xA9 |
52 | #define ADT7462_REG_FAN_ENABLE 0x07 | 51 | #define ADT7462_REG_FAN_ENABLE 0x07 |
53 | #define ADT7462_REG_FAN_MIN_BASE_ADDR 0x78 | 52 | #define ADT7462_REG_FAN_MIN_BASE_ADDR 0x78 |
54 | #define ADT7462_REG_FAN_MIN_MAX_ADDR 0x7F | 53 | #define ADT7462_REG_FAN_MIN_MAX_ADDR 0x7F |
55 | 54 | ||
56 | #define ADT7462_REG_CFG2 0x02 | 55 | #define ADT7462_REG_CFG2 0x02 |
57 | #define ADT7462_FSPD_MASK 0x20 | 56 | #define ADT7462_FSPD_MASK 0x20 |
58 | 57 | ||
59 | #define ADT7462_REG_PWM_BASE_ADDR 0xAA | 58 | #define ADT7462_REG_PWM_BASE_ADDR 0xAA |
60 | #define ADT7462_REG_PWM_MAX_ADDR 0xAD | 59 | #define ADT7462_REG_PWM_MAX_ADDR 0xAD |
61 | #define ADT7462_REG_PWM_MIN_BASE_ADDR 0x28 | 60 | #define ADT7462_REG_PWM_MIN_BASE_ADDR 0x28 |
62 | #define ADT7462_REG_PWM_MIN_MAX_ADDR 0x2B | 61 | #define ADT7462_REG_PWM_MIN_MAX_ADDR 0x2B |
63 | #define ADT7462_REG_PWM_MAX 0x2C | 62 | #define ADT7462_REG_PWM_MAX 0x2C |
64 | #define ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR 0x5C | 63 | #define ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR 0x5C |
65 | #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR 0x5F | 64 | #define ADT7462_REG_PWM_TEMP_MIN_MAX_ADDR 0x5F |
66 | #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR 0x60 | 65 | #define ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR 0x60 |
67 | #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR 0x63 | 66 | #define ADT7462_REG_PWM_TEMP_RANGE_MAX_ADDR 0x63 |
68 | #define ADT7462_PWM_HYST_MASK 0x0F | 67 | #define ADT7462_PWM_HYST_MASK 0x0F |
69 | #define ADT7462_PWM_RANGE_MASK 0xF0 | 68 | #define ADT7462_PWM_RANGE_MASK 0xF0 |
70 | #define ADT7462_PWM_RANGE_SHIFT 4 | 69 | #define ADT7462_PWM_RANGE_SHIFT 4 |
71 | #define ADT7462_REG_PWM_CFG_BASE_ADDR 0x21 | 70 | #define ADT7462_REG_PWM_CFG_BASE_ADDR 0x21 |
72 | #define ADT7462_REG_PWM_CFG_MAX_ADDR 0x24 | 71 | #define ADT7462_REG_PWM_CFG_MAX_ADDR 0x24 |
73 | #define ADT7462_PWM_CHANNEL_MASK 0xE0 | 72 | #define ADT7462_PWM_CHANNEL_MASK 0xE0 |
74 | #define ADT7462_PWM_CHANNEL_SHIFT 5 | 73 | #define ADT7462_PWM_CHANNEL_SHIFT 5 |
75 | 74 | ||
76 | #define ADT7462_REG_PIN_CFG_BASE_ADDR 0x10 | 75 | #define ADT7462_REG_PIN_CFG_BASE_ADDR 0x10 |
77 | #define ADT7462_REG_PIN_CFG_MAX_ADDR 0x13 | 76 | #define ADT7462_REG_PIN_CFG_MAX_ADDR 0x13 |
78 | #define ADT7462_PIN7_INPUT 0x01 /* cfg0 */ | 77 | #define ADT7462_PIN7_INPUT 0x01 /* cfg0 */ |
79 | #define ADT7462_DIODE3_INPUT 0x20 | 78 | #define ADT7462_DIODE3_INPUT 0x20 |
80 | #define ADT7462_DIODE1_INPUT 0x40 | 79 | #define ADT7462_DIODE1_INPUT 0x40 |
81 | #define ADT7462_VID_INPUT 0x80 | 80 | #define ADT7462_VID_INPUT 0x80 |
82 | #define ADT7462_PIN22_INPUT 0x04 /* cfg1 */ | 81 | #define ADT7462_PIN22_INPUT 0x04 /* cfg1 */ |
83 | #define ADT7462_PIN21_INPUT 0x08 | 82 | #define ADT7462_PIN21_INPUT 0x08 |
84 | #define ADT7462_PIN19_INPUT 0x10 | 83 | #define ADT7462_PIN19_INPUT 0x10 |
85 | #define ADT7462_PIN15_INPUT 0x20 | 84 | #define ADT7462_PIN15_INPUT 0x20 |
86 | #define ADT7462_PIN13_INPUT 0x40 | 85 | #define ADT7462_PIN13_INPUT 0x40 |
87 | #define ADT7462_PIN8_INPUT 0x80 | 86 | #define ADT7462_PIN8_INPUT 0x80 |
88 | #define ADT7462_PIN23_MASK 0x03 | 87 | #define ADT7462_PIN23_MASK 0x03 |
89 | #define ADT7462_PIN23_SHIFT 0 | 88 | #define ADT7462_PIN23_SHIFT 0 |
90 | #define ADT7462_PIN26_MASK 0x0C /* cfg2 */ | 89 | #define ADT7462_PIN26_MASK 0x0C /* cfg2 */ |
91 | #define ADT7462_PIN26_SHIFT 2 | 90 | #define ADT7462_PIN26_SHIFT 2 |
92 | #define ADT7462_PIN25_MASK 0x30 | 91 | #define ADT7462_PIN25_MASK 0x30 |
93 | #define ADT7462_PIN25_SHIFT 4 | 92 | #define ADT7462_PIN25_SHIFT 4 |
94 | #define ADT7462_PIN24_MASK 0xC0 | 93 | #define ADT7462_PIN24_MASK 0xC0 |
95 | #define ADT7462_PIN24_SHIFT 6 | 94 | #define ADT7462_PIN24_SHIFT 6 |
96 | #define ADT7462_PIN26_VOLT_INPUT 0x08 | 95 | #define ADT7462_PIN26_VOLT_INPUT 0x08 |
97 | #define ADT7462_PIN25_VOLT_INPUT 0x20 | 96 | #define ADT7462_PIN25_VOLT_INPUT 0x20 |
98 | #define ADT7462_PIN28_SHIFT 4 /* cfg3 */ | 97 | #define ADT7462_PIN28_SHIFT 4 /* cfg3 */ |
99 | #define ADT7462_PIN28_VOLT 0x5 | 98 | #define ADT7462_PIN28_VOLT 0x5 |
100 | 99 | ||
101 | #define ADT7462_REG_ALARM1 0xB8 | 100 | #define ADT7462_REG_ALARM1 0xB8 |
102 | #define ADT7462_LT_ALARM 0x02 | 101 | #define ADT7462_LT_ALARM 0x02 |
103 | #define ADT7462_R1T_ALARM 0x04 | 102 | #define ADT7462_R1T_ALARM 0x04 |
104 | #define ADT7462_R2T_ALARM 0x08 | 103 | #define ADT7462_R2T_ALARM 0x08 |
105 | #define ADT7462_R3T_ALARM 0x10 | 104 | #define ADT7462_R3T_ALARM 0x10 |
106 | #define ADT7462_REG_ALARM2 0xBB | 105 | #define ADT7462_REG_ALARM2 0xBB |
107 | #define ADT7462_V0_ALARM 0x01 | 106 | #define ADT7462_V0_ALARM 0x01 |
108 | #define ADT7462_V1_ALARM 0x02 | 107 | #define ADT7462_V1_ALARM 0x02 |
109 | #define ADT7462_V2_ALARM 0x04 | 108 | #define ADT7462_V2_ALARM 0x04 |
110 | #define ADT7462_V3_ALARM 0x08 | 109 | #define ADT7462_V3_ALARM 0x08 |
111 | #define ADT7462_V4_ALARM 0x10 | 110 | #define ADT7462_V4_ALARM 0x10 |
112 | #define ADT7462_V5_ALARM 0x20 | 111 | #define ADT7462_V5_ALARM 0x20 |
113 | #define ADT7462_V6_ALARM 0x40 | 112 | #define ADT7462_V6_ALARM 0x40 |
114 | #define ADT7462_V7_ALARM 0x80 | 113 | #define ADT7462_V7_ALARM 0x80 |
115 | #define ADT7462_REG_ALARM3 0xBC | 114 | #define ADT7462_REG_ALARM3 0xBC |
116 | #define ADT7462_V8_ALARM 0x08 | 115 | #define ADT7462_V8_ALARM 0x08 |
117 | #define ADT7462_V9_ALARM 0x10 | 116 | #define ADT7462_V9_ALARM 0x10 |
118 | #define ADT7462_V10_ALARM 0x20 | 117 | #define ADT7462_V10_ALARM 0x20 |
119 | #define ADT7462_V11_ALARM 0x40 | 118 | #define ADT7462_V11_ALARM 0x40 |
120 | #define ADT7462_V12_ALARM 0x80 | 119 | #define ADT7462_V12_ALARM 0x80 |
121 | #define ADT7462_REG_ALARM4 0xBD | 120 | #define ADT7462_REG_ALARM4 0xBD |
122 | #define ADT7462_F0_ALARM 0x01 | 121 | #define ADT7462_F0_ALARM 0x01 |
123 | #define ADT7462_F1_ALARM 0x02 | 122 | #define ADT7462_F1_ALARM 0x02 |
124 | #define ADT7462_F2_ALARM 0x04 | 123 | #define ADT7462_F2_ALARM 0x04 |
125 | #define ADT7462_F3_ALARM 0x08 | 124 | #define ADT7462_F3_ALARM 0x08 |
126 | #define ADT7462_F4_ALARM 0x10 | 125 | #define ADT7462_F4_ALARM 0x10 |
127 | #define ADT7462_F5_ALARM 0x20 | 126 | #define ADT7462_F5_ALARM 0x20 |
128 | #define ADT7462_F6_ALARM 0x40 | 127 | #define ADT7462_F6_ALARM 0x40 |
129 | #define ADT7462_F7_ALARM 0x80 | 128 | #define ADT7462_F7_ALARM 0x80 |
130 | #define ADT7462_ALARM1 0x0000 | 129 | #define ADT7462_ALARM1 0x0000 |
131 | #define ADT7462_ALARM2 0x0100 | 130 | #define ADT7462_ALARM2 0x0100 |
132 | #define ADT7462_ALARM3 0x0200 | 131 | #define ADT7462_ALARM3 0x0200 |
133 | #define ADT7462_ALARM4 0x0300 | 132 | #define ADT7462_ALARM4 0x0300 |
134 | #define ADT7462_ALARM_REG_SHIFT 8 | 133 | #define ADT7462_ALARM_REG_SHIFT 8 |
135 | #define ADT7462_ALARM_FLAG_MASK 0x0F | 134 | #define ADT7462_ALARM_FLAG_MASK 0x0F |
136 | 135 | ||
137 | #define ADT7462_TEMP_COUNT 4 | 136 | #define ADT7462_TEMP_COUNT 4 |
138 | #define ADT7462_TEMP_REG(x) (ADT7462_REG_TEMP_BASE_ADDR + ((x) * 2)) | 137 | #define ADT7462_TEMP_REG(x) (ADT7462_REG_TEMP_BASE_ADDR + ((x) * 2)) |
139 | #define ADT7462_TEMP_MIN_REG(x) (ADT7462_REG_MIN_TEMP_BASE_ADDR + (x)) | 138 | #define ADT7462_TEMP_MIN_REG(x) (ADT7462_REG_MIN_TEMP_BASE_ADDR + (x)) |
140 | #define ADT7462_TEMP_MAX_REG(x) (ADT7462_REG_MAX_TEMP_BASE_ADDR + (x)) | 139 | #define ADT7462_TEMP_MAX_REG(x) (ADT7462_REG_MAX_TEMP_BASE_ADDR + (x)) |
141 | #define TEMP_FRAC_OFFSET 6 | 140 | #define TEMP_FRAC_OFFSET 6 |
142 | 141 | ||
143 | #define ADT7462_FAN_COUNT 8 | 142 | #define ADT7462_FAN_COUNT 8 |
144 | #define ADT7462_REG_FAN_MIN(x) (ADT7462_REG_FAN_MIN_BASE_ADDR + (x)) | 143 | #define ADT7462_REG_FAN_MIN(x) (ADT7462_REG_FAN_MIN_BASE_ADDR + (x)) |
145 | 144 | ||
146 | #define ADT7462_PWM_COUNT 4 | 145 | #define ADT7462_PWM_COUNT 4 |
147 | #define ADT7462_REG_PWM(x) (ADT7462_REG_PWM_BASE_ADDR + (x)) | 146 | #define ADT7462_REG_PWM(x) (ADT7462_REG_PWM_BASE_ADDR + (x)) |
148 | #define ADT7462_REG_PWM_MIN(x) (ADT7462_REG_PWM_MIN_BASE_ADDR + (x)) | 147 | #define ADT7462_REG_PWM_MIN(x) (ADT7462_REG_PWM_MIN_BASE_ADDR + (x)) |
149 | #define ADT7462_REG_PWM_TMIN(x) \ | 148 | #define ADT7462_REG_PWM_TMIN(x) \ |
150 | (ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR + (x)) | 149 | (ADT7462_REG_PWM_TEMP_MIN_BASE_ADDR + (x)) |
151 | #define ADT7462_REG_PWM_TRANGE(x) \ | 150 | #define ADT7462_REG_PWM_TRANGE(x) \ |
152 | (ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR + (x)) | 151 | (ADT7462_REG_PWM_TEMP_RANGE_BASE_ADDR + (x)) |
153 | 152 | ||
154 | #define ADT7462_PIN_CFG_REG_COUNT 4 | 153 | #define ADT7462_PIN_CFG_REG_COUNT 4 |
155 | #define ADT7462_REG_PIN_CFG(x) (ADT7462_REG_PIN_CFG_BASE_ADDR + (x)) | 154 | #define ADT7462_REG_PIN_CFG(x) (ADT7462_REG_PIN_CFG_BASE_ADDR + (x)) |
156 | #define ADT7462_REG_PWM_CFG(x) (ADT7462_REG_PWM_CFG_BASE_ADDR + (x)) | 155 | #define ADT7462_REG_PWM_CFG(x) (ADT7462_REG_PWM_CFG_BASE_ADDR + (x)) |
157 | 156 | ||
158 | #define ADT7462_ALARM_REG_COUNT 4 | 157 | #define ADT7462_ALARM_REG_COUNT 4 |
159 | 158 | ||
160 | /* | 159 | /* |
161 | * The chip can measure 13 different voltage sources: | 160 | * The chip can measure 13 different voltage sources: |
162 | * | 161 | * |
163 | * 1. +12V1 (pin 7) | 162 | * 1. +12V1 (pin 7) |
164 | * 2. Vccp1/+2.5V/+1.8V/+1.5V (pin 23) | 163 | * 2. Vccp1/+2.5V/+1.8V/+1.5V (pin 23) |
165 | * 3. +12V3 (pin 22) | 164 | * 3. +12V3 (pin 22) |
166 | * 4. +5V (pin 21) | 165 | * 4. +5V (pin 21) |
167 | * 5. +1.25V/+0.9V (pin 19) | 166 | * 5. +1.25V/+0.9V (pin 19) |
168 | * 6. +2.5V/+1.8V (pin 15) | 167 | * 6. +2.5V/+1.8V (pin 15) |
169 | * 7. +3.3v (pin 13) | 168 | * 7. +3.3v (pin 13) |
170 | * 8. +12V2 (pin 8) | 169 | * 8. +12V2 (pin 8) |
171 | * 9. Vbatt/FSB_Vtt (pin 26) | 170 | * 9. Vbatt/FSB_Vtt (pin 26) |
172 | * A. +3.3V/+1.2V1 (pin 25) | 171 | * A. +3.3V/+1.2V1 (pin 25) |
173 | * B. Vccp2/+2.5V/+1.8V/+1.5V (pin 24) | 172 | * B. Vccp2/+2.5V/+1.8V/+1.5V (pin 24) |
174 | * C. +1.5V ICH (only if BOTH pin 28/29 are set to +1.5V) | 173 | * C. +1.5V ICH (only if BOTH pin 28/29 are set to +1.5V) |
175 | * D. +1.5V 3GPIO (only if BOTH pin 28/29 are set to +1.5V) | 174 | * D. +1.5V 3GPIO (only if BOTH pin 28/29 are set to +1.5V) |
176 | * | 175 | * |
177 | * Each of these 13 has a factor to convert raw to voltage. Even better, | 176 | * Each of these 13 has a factor to convert raw to voltage. Even better, |
178 | * the pins can be connected to other sensors (tach/gpio/hot/etc), which | 177 | * the pins can be connected to other sensors (tach/gpio/hot/etc), which |
179 | * makes the bookkeeping tricky. | 178 | * makes the bookkeeping tricky. |
180 | * | 179 | * |
181 | * Some, but not all, of these voltages have low/high limits. | 180 | * Some, but not all, of these voltages have low/high limits. |
182 | */ | 181 | */ |
183 | #define ADT7462_VOLT_COUNT 13 | 182 | #define ADT7462_VOLT_COUNT 13 |
184 | 183 | ||
185 | #define ADT7462_VENDOR 0x41 | 184 | #define ADT7462_VENDOR 0x41 |
186 | #define ADT7462_DEVICE 0x62 | 185 | #define ADT7462_DEVICE 0x62 |
187 | /* datasheet only mentions a revision 4 */ | 186 | /* datasheet only mentions a revision 4 */ |
188 | #define ADT7462_REVISION 0x04 | 187 | #define ADT7462_REVISION 0x04 |
189 | 188 | ||
190 | /* How often do we reread sensors values? (In jiffies) */ | 189 | /* How often do we reread sensors values? (In jiffies) */ |
191 | #define SENSOR_REFRESH_INTERVAL (2 * HZ) | 190 | #define SENSOR_REFRESH_INTERVAL (2 * HZ) |
192 | 191 | ||
193 | /* How often do we reread sensor limit values? (In jiffies) */ | 192 | /* How often do we reread sensor limit values? (In jiffies) */ |
194 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) | 193 | #define LIMIT_REFRESH_INTERVAL (60 * HZ) |
195 | 194 | ||
196 | /* datasheet says to divide this number by the fan reading to get fan rpm */ | 195 | /* datasheet says to divide this number by the fan reading to get fan rpm */ |
197 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) | 196 | #define FAN_PERIOD_TO_RPM(x) ((90000 * 60) / (x)) |
198 | #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM | 197 | #define FAN_RPM_TO_PERIOD FAN_PERIOD_TO_RPM |
199 | #define FAN_PERIOD_INVALID 65535 | 198 | #define FAN_PERIOD_INVALID 65535 |
200 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) | 199 | #define FAN_DATA_VALID(x) ((x) && (x) != FAN_PERIOD_INVALID) |
201 | 200 | ||
202 | #define MASK_AND_SHIFT(value, prefix) \ | 201 | #define MASK_AND_SHIFT(value, prefix) \ |
203 | (((value) & prefix##_MASK) >> prefix##_SHIFT) | 202 | (((value) & prefix##_MASK) >> prefix##_SHIFT) |
204 | 203 | ||
205 | struct adt7462_data { | 204 | struct adt7462_data { |
206 | struct device *hwmon_dev; | 205 | struct device *hwmon_dev; |
207 | struct attribute_group attrs; | 206 | struct attribute_group attrs; |
208 | struct mutex lock; | 207 | struct mutex lock; |
209 | char sensors_valid; | 208 | char sensors_valid; |
210 | char limits_valid; | 209 | char limits_valid; |
211 | unsigned long sensors_last_updated; /* In jiffies */ | 210 | unsigned long sensors_last_updated; /* In jiffies */ |
212 | unsigned long limits_last_updated; /* In jiffies */ | 211 | unsigned long limits_last_updated; /* In jiffies */ |
213 | 212 | ||
214 | u8 temp[ADT7462_TEMP_COUNT]; | 213 | u8 temp[ADT7462_TEMP_COUNT]; |
215 | /* bits 6-7 are quarter pieces of temp */ | 214 | /* bits 6-7 are quarter pieces of temp */ |
216 | u8 temp_frac[ADT7462_TEMP_COUNT]; | 215 | u8 temp_frac[ADT7462_TEMP_COUNT]; |
217 | u8 temp_min[ADT7462_TEMP_COUNT]; | 216 | u8 temp_min[ADT7462_TEMP_COUNT]; |
218 | u8 temp_max[ADT7462_TEMP_COUNT]; | 217 | u8 temp_max[ADT7462_TEMP_COUNT]; |
219 | u16 fan[ADT7462_FAN_COUNT]; | 218 | u16 fan[ADT7462_FAN_COUNT]; |
220 | u8 fan_enabled; | 219 | u8 fan_enabled; |
221 | u8 fan_min[ADT7462_FAN_COUNT]; | 220 | u8 fan_min[ADT7462_FAN_COUNT]; |
222 | u8 cfg2; | 221 | u8 cfg2; |
223 | u8 pwm[ADT7462_PWM_COUNT]; | 222 | u8 pwm[ADT7462_PWM_COUNT]; |
224 | u8 pin_cfg[ADT7462_PIN_CFG_REG_COUNT]; | 223 | u8 pin_cfg[ADT7462_PIN_CFG_REG_COUNT]; |
225 | u8 voltages[ADT7462_VOLT_COUNT]; | 224 | u8 voltages[ADT7462_VOLT_COUNT]; |
226 | u8 volt_max[ADT7462_VOLT_COUNT]; | 225 | u8 volt_max[ADT7462_VOLT_COUNT]; |
227 | u8 volt_min[ADT7462_VOLT_COUNT]; | 226 | u8 volt_min[ADT7462_VOLT_COUNT]; |
228 | u8 pwm_min[ADT7462_PWM_COUNT]; | 227 | u8 pwm_min[ADT7462_PWM_COUNT]; |
229 | u8 pwm_tmin[ADT7462_PWM_COUNT]; | 228 | u8 pwm_tmin[ADT7462_PWM_COUNT]; |
230 | u8 pwm_trange[ADT7462_PWM_COUNT]; | 229 | u8 pwm_trange[ADT7462_PWM_COUNT]; |
231 | u8 pwm_max; /* only one per chip */ | 230 | u8 pwm_max; /* only one per chip */ |
232 | u8 pwm_cfg[ADT7462_PWM_COUNT]; | 231 | u8 pwm_cfg[ADT7462_PWM_COUNT]; |
233 | u8 alarms[ADT7462_ALARM_REG_COUNT]; | 232 | u8 alarms[ADT7462_ALARM_REG_COUNT]; |
234 | }; | 233 | }; |
235 | 234 | ||
236 | static int adt7462_probe(struct i2c_client *client, | 235 | static int adt7462_probe(struct i2c_client *client, |
237 | const struct i2c_device_id *id); | 236 | const struct i2c_device_id *id); |
238 | static int adt7462_detect(struct i2c_client *client, | 237 | static int adt7462_detect(struct i2c_client *client, |
239 | struct i2c_board_info *info); | 238 | struct i2c_board_info *info); |
240 | static int adt7462_remove(struct i2c_client *client); | 239 | static int adt7462_remove(struct i2c_client *client); |
241 | 240 | ||
242 | static const struct i2c_device_id adt7462_id[] = { | 241 | static const struct i2c_device_id adt7462_id[] = { |
243 | { "adt7462", 0 }, | 242 | { "adt7462", 0 }, |
244 | { } | 243 | { } |
245 | }; | 244 | }; |
246 | MODULE_DEVICE_TABLE(i2c, adt7462_id); | 245 | MODULE_DEVICE_TABLE(i2c, adt7462_id); |
247 | 246 | ||
248 | static struct i2c_driver adt7462_driver = { | 247 | static struct i2c_driver adt7462_driver = { |
249 | .class = I2C_CLASS_HWMON, | 248 | .class = I2C_CLASS_HWMON, |
250 | .driver = { | 249 | .driver = { |
251 | .name = "adt7462", | 250 | .name = "adt7462", |
252 | }, | 251 | }, |
253 | .probe = adt7462_probe, | 252 | .probe = adt7462_probe, |
254 | .remove = adt7462_remove, | 253 | .remove = adt7462_remove, |
255 | .id_table = adt7462_id, | 254 | .id_table = adt7462_id, |
256 | .detect = adt7462_detect, | 255 | .detect = adt7462_detect, |
257 | .address_list = normal_i2c, | 256 | .address_list = normal_i2c, |
258 | }; | 257 | }; |
259 | 258 | ||
260 | /* | 259 | /* |
261 | * 16-bit registers on the ADT7462 are low-byte first. The data sheet says | 260 | * 16-bit registers on the ADT7462 are low-byte first. The data sheet says |
262 | * that the low byte must be read before the high byte. | 261 | * that the low byte must be read before the high byte. |
263 | */ | 262 | */ |
264 | static inline int adt7462_read_word_data(struct i2c_client *client, u8 reg) | 263 | static inline int adt7462_read_word_data(struct i2c_client *client, u8 reg) |
265 | { | 264 | { |
266 | u16 foo; | 265 | u16 foo; |
267 | foo = i2c_smbus_read_byte_data(client, reg); | 266 | foo = i2c_smbus_read_byte_data(client, reg); |
268 | foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); | 267 | foo |= ((u16)i2c_smbus_read_byte_data(client, reg + 1) << 8); |
269 | return foo; | 268 | return foo; |
270 | } | 269 | } |
271 | 270 | ||
272 | /* For some reason these registers are not contiguous. */ | 271 | /* For some reason these registers are not contiguous. */ |
273 | static int ADT7462_REG_FAN(int fan) | 272 | static int ADT7462_REG_FAN(int fan) |
274 | { | 273 | { |
275 | if (fan < 4) | 274 | if (fan < 4) |
276 | return ADT7462_REG_FAN_BASE_ADDR + (2 * fan); | 275 | return ADT7462_REG_FAN_BASE_ADDR + (2 * fan); |
277 | return ADT7462_REG_FAN2_BASE_ADDR + (2 * (fan - 4)); | 276 | return ADT7462_REG_FAN2_BASE_ADDR + (2 * (fan - 4)); |
278 | } | 277 | } |
279 | 278 | ||
280 | /* Voltage registers are scattered everywhere */ | 279 | /* Voltage registers are scattered everywhere */ |
281 | static int ADT7462_REG_VOLT_MAX(struct adt7462_data *data, int which) | 280 | static int ADT7462_REG_VOLT_MAX(struct adt7462_data *data, int which) |
282 | { | 281 | { |
283 | switch (which) { | 282 | switch (which) { |
284 | case 0: | 283 | case 0: |
285 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | 284 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) |
286 | return 0x7C; | 285 | return 0x7C; |
287 | break; | 286 | break; |
288 | case 1: | 287 | case 1: |
289 | return 0x69; | 288 | return 0x69; |
290 | case 2: | 289 | case 2: |
291 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | 290 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) |
292 | return 0x7F; | 291 | return 0x7F; |
293 | break; | 292 | break; |
294 | case 3: | 293 | case 3: |
295 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | 294 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) |
296 | return 0x7E; | 295 | return 0x7E; |
297 | break; | 296 | break; |
298 | case 4: | 297 | case 4: |
299 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | 298 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) |
300 | return 0x4B; | 299 | return 0x4B; |
301 | break; | 300 | break; |
302 | case 5: | 301 | case 5: |
303 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | 302 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) |
304 | return 0x49; | 303 | return 0x49; |
305 | break; | 304 | break; |
306 | case 6: | 305 | case 6: |
307 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | 306 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) |
308 | return 0x68; | 307 | return 0x68; |
309 | break; | 308 | break; |
310 | case 7: | 309 | case 7: |
311 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | 310 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) |
312 | return 0x7D; | 311 | return 0x7D; |
313 | break; | 312 | break; |
314 | case 8: | 313 | case 8: |
315 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | 314 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) |
316 | return 0x6C; | 315 | return 0x6C; |
317 | break; | 316 | break; |
318 | case 9: | 317 | case 9: |
319 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | 318 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) |
320 | return 0x6B; | 319 | return 0x6B; |
321 | break; | 320 | break; |
322 | case 10: | 321 | case 10: |
323 | return 0x6A; | 322 | return 0x6A; |
324 | case 11: | 323 | case 11: |
325 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 324 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
326 | ADT7462_PIN28_VOLT && | 325 | ADT7462_PIN28_VOLT && |
327 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 326 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
328 | return 0x50; | 327 | return 0x50; |
329 | break; | 328 | break; |
330 | case 12: | 329 | case 12: |
331 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 330 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
332 | ADT7462_PIN28_VOLT && | 331 | ADT7462_PIN28_VOLT && |
333 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 332 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
334 | return 0x4C; | 333 | return 0x4C; |
335 | break; | 334 | break; |
336 | } | 335 | } |
337 | return -ENODEV; | 336 | return -ENODEV; |
338 | } | 337 | } |
339 | 338 | ||
340 | static int ADT7462_REG_VOLT_MIN(struct adt7462_data *data, int which) | 339 | static int ADT7462_REG_VOLT_MIN(struct adt7462_data *data, int which) |
341 | { | 340 | { |
342 | switch (which) { | 341 | switch (which) { |
343 | case 0: | 342 | case 0: |
344 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | 343 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) |
345 | return 0x6D; | 344 | return 0x6D; |
346 | break; | 345 | break; |
347 | case 1: | 346 | case 1: |
348 | return 0x72; | 347 | return 0x72; |
349 | case 2: | 348 | case 2: |
350 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | 349 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) |
351 | return 0x6F; | 350 | return 0x6F; |
352 | break; | 351 | break; |
353 | case 3: | 352 | case 3: |
354 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | 353 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) |
355 | return 0x71; | 354 | return 0x71; |
356 | break; | 355 | break; |
357 | case 4: | 356 | case 4: |
358 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | 357 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) |
359 | return 0x47; | 358 | return 0x47; |
360 | break; | 359 | break; |
361 | case 5: | 360 | case 5: |
362 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | 361 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) |
363 | return 0x45; | 362 | return 0x45; |
364 | break; | 363 | break; |
365 | case 6: | 364 | case 6: |
366 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | 365 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) |
367 | return 0x70; | 366 | return 0x70; |
368 | break; | 367 | break; |
369 | case 7: | 368 | case 7: |
370 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | 369 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) |
371 | return 0x6E; | 370 | return 0x6E; |
372 | break; | 371 | break; |
373 | case 8: | 372 | case 8: |
374 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | 373 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) |
375 | return 0x75; | 374 | return 0x75; |
376 | break; | 375 | break; |
377 | case 9: | 376 | case 9: |
378 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | 377 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) |
379 | return 0x74; | 378 | return 0x74; |
380 | break; | 379 | break; |
381 | case 10: | 380 | case 10: |
382 | return 0x73; | 381 | return 0x73; |
383 | case 11: | 382 | case 11: |
384 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 383 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
385 | ADT7462_PIN28_VOLT && | 384 | ADT7462_PIN28_VOLT && |
386 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 385 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
387 | return 0x76; | 386 | return 0x76; |
388 | break; | 387 | break; |
389 | case 12: | 388 | case 12: |
390 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 389 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
391 | ADT7462_PIN28_VOLT && | 390 | ADT7462_PIN28_VOLT && |
392 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 391 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
393 | return 0x77; | 392 | return 0x77; |
394 | break; | 393 | break; |
395 | } | 394 | } |
396 | return -ENODEV; | 395 | return -ENODEV; |
397 | } | 396 | } |
398 | 397 | ||
399 | static int ADT7462_REG_VOLT(struct adt7462_data *data, int which) | 398 | static int ADT7462_REG_VOLT(struct adt7462_data *data, int which) |
400 | { | 399 | { |
401 | switch (which) { | 400 | switch (which) { |
402 | case 0: | 401 | case 0: |
403 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | 402 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) |
404 | return 0xA3; | 403 | return 0xA3; |
405 | break; | 404 | break; |
406 | case 1: | 405 | case 1: |
407 | return 0x90; | 406 | return 0x90; |
408 | case 2: | 407 | case 2: |
409 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | 408 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) |
410 | return 0xA9; | 409 | return 0xA9; |
411 | break; | 410 | break; |
412 | case 3: | 411 | case 3: |
413 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | 412 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) |
414 | return 0xA7; | 413 | return 0xA7; |
415 | break; | 414 | break; |
416 | case 4: | 415 | case 4: |
417 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) | 416 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) |
418 | return 0x8F; | 417 | return 0x8F; |
419 | break; | 418 | break; |
420 | case 5: | 419 | case 5: |
421 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) | 420 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) |
422 | return 0x8B; | 421 | return 0x8B; |
423 | break; | 422 | break; |
424 | case 6: | 423 | case 6: |
425 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | 424 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) |
426 | return 0x96; | 425 | return 0x96; |
427 | break; | 426 | break; |
428 | case 7: | 427 | case 7: |
429 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | 428 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) |
430 | return 0xA5; | 429 | return 0xA5; |
431 | break; | 430 | break; |
432 | case 8: | 431 | case 8: |
433 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) | 432 | if (!(data->pin_cfg[2] & ADT7462_PIN26_VOLT_INPUT)) |
434 | return 0x93; | 433 | return 0x93; |
435 | break; | 434 | break; |
436 | case 9: | 435 | case 9: |
437 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) | 436 | if (!(data->pin_cfg[2] & ADT7462_PIN25_VOLT_INPUT)) |
438 | return 0x92; | 437 | return 0x92; |
439 | break; | 438 | break; |
440 | case 10: | 439 | case 10: |
441 | return 0x91; | 440 | return 0x91; |
442 | case 11: | 441 | case 11: |
443 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 442 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
444 | ADT7462_PIN28_VOLT && | 443 | ADT7462_PIN28_VOLT && |
445 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 444 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
446 | return 0x94; | 445 | return 0x94; |
447 | break; | 446 | break; |
448 | case 12: | 447 | case 12: |
449 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 448 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
450 | ADT7462_PIN28_VOLT && | 449 | ADT7462_PIN28_VOLT && |
451 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 450 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
452 | return 0x95; | 451 | return 0x95; |
453 | break; | 452 | break; |
454 | } | 453 | } |
455 | return -ENODEV; | 454 | return -ENODEV; |
456 | } | 455 | } |
457 | 456 | ||
458 | /* Provide labels for sysfs */ | 457 | /* Provide labels for sysfs */ |
459 | static const char *voltage_label(struct adt7462_data *data, int which) | 458 | static const char *voltage_label(struct adt7462_data *data, int which) |
460 | { | 459 | { |
461 | switch (which) { | 460 | switch (which) { |
462 | case 0: | 461 | case 0: |
463 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | 462 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) |
464 | return "+12V1"; | 463 | return "+12V1"; |
465 | break; | 464 | break; |
466 | case 1: | 465 | case 1: |
467 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { | 466 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { |
468 | case 0: | 467 | case 0: |
469 | return "Vccp1"; | 468 | return "Vccp1"; |
470 | case 1: | 469 | case 1: |
471 | return "+2.5V"; | 470 | return "+2.5V"; |
472 | case 2: | 471 | case 2: |
473 | return "+1.8V"; | 472 | return "+1.8V"; |
474 | case 3: | 473 | case 3: |
475 | return "+1.5V"; | 474 | return "+1.5V"; |
476 | } | 475 | } |
477 | case 2: | 476 | case 2: |
478 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | 477 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) |
479 | return "+12V3"; | 478 | return "+12V3"; |
480 | break; | 479 | break; |
481 | case 3: | 480 | case 3: |
482 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | 481 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) |
483 | return "+5V"; | 482 | return "+5V"; |
484 | break; | 483 | break; |
485 | case 4: | 484 | case 4: |
486 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { | 485 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { |
487 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | 486 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) |
488 | return "+0.9V"; | 487 | return "+0.9V"; |
489 | return "+1.25V"; | 488 | return "+1.25V"; |
490 | } | 489 | } |
491 | break; | 490 | break; |
492 | case 5: | 491 | case 5: |
493 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { | 492 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { |
494 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | 493 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) |
495 | return "+1.8V"; | 494 | return "+1.8V"; |
496 | return "+2.5V"; | 495 | return "+2.5V"; |
497 | } | 496 | } |
498 | break; | 497 | break; |
499 | case 6: | 498 | case 6: |
500 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | 499 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) |
501 | return "+3.3V"; | 500 | return "+3.3V"; |
502 | break; | 501 | break; |
503 | case 7: | 502 | case 7: |
504 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | 503 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) |
505 | return "+12V2"; | 504 | return "+12V2"; |
506 | break; | 505 | break; |
507 | case 8: | 506 | case 8: |
508 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { | 507 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { |
509 | case 0: | 508 | case 0: |
510 | return "Vbatt"; | 509 | return "Vbatt"; |
511 | case 1: | 510 | case 1: |
512 | return "FSB_Vtt"; | 511 | return "FSB_Vtt"; |
513 | } | 512 | } |
514 | break; | 513 | break; |
515 | case 9: | 514 | case 9: |
516 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { | 515 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { |
517 | case 0: | 516 | case 0: |
518 | return "+3.3V"; | 517 | return "+3.3V"; |
519 | case 1: | 518 | case 1: |
520 | return "+1.2V1"; | 519 | return "+1.2V1"; |
521 | } | 520 | } |
522 | break; | 521 | break; |
523 | case 10: | 522 | case 10: |
524 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { | 523 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { |
525 | case 0: | 524 | case 0: |
526 | return "Vccp2"; | 525 | return "Vccp2"; |
527 | case 1: | 526 | case 1: |
528 | return "+2.5V"; | 527 | return "+2.5V"; |
529 | case 2: | 528 | case 2: |
530 | return "+1.8V"; | 529 | return "+1.8V"; |
531 | case 3: | 530 | case 3: |
532 | return "+1.5"; | 531 | return "+1.5"; |
533 | } | 532 | } |
534 | case 11: | 533 | case 11: |
535 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 534 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
536 | ADT7462_PIN28_VOLT && | 535 | ADT7462_PIN28_VOLT && |
537 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 536 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
538 | return "+1.5V ICH"; | 537 | return "+1.5V ICH"; |
539 | break; | 538 | break; |
540 | case 12: | 539 | case 12: |
541 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 540 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
542 | ADT7462_PIN28_VOLT && | 541 | ADT7462_PIN28_VOLT && |
543 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 542 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
544 | return "+1.5V 3GPIO"; | 543 | return "+1.5V 3GPIO"; |
545 | break; | 544 | break; |
546 | } | 545 | } |
547 | return "N/A"; | 546 | return "N/A"; |
548 | } | 547 | } |
549 | 548 | ||
550 | /* Multipliers are actually in uV, not mV. */ | 549 | /* Multipliers are actually in uV, not mV. */ |
551 | static int voltage_multiplier(struct adt7462_data *data, int which) | 550 | static int voltage_multiplier(struct adt7462_data *data, int which) |
552 | { | 551 | { |
553 | switch (which) { | 552 | switch (which) { |
554 | case 0: | 553 | case 0: |
555 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) | 554 | if (!(data->pin_cfg[0] & ADT7462_PIN7_INPUT)) |
556 | return 62500; | 555 | return 62500; |
557 | break; | 556 | break; |
558 | case 1: | 557 | case 1: |
559 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { | 558 | switch (MASK_AND_SHIFT(data->pin_cfg[1], ADT7462_PIN23)) { |
560 | case 0: | 559 | case 0: |
561 | if (data->pin_cfg[0] & ADT7462_VID_INPUT) | 560 | if (data->pin_cfg[0] & ADT7462_VID_INPUT) |
562 | return 12500; | 561 | return 12500; |
563 | return 6250; | 562 | return 6250; |
564 | case 1: | 563 | case 1: |
565 | return 13000; | 564 | return 13000; |
566 | case 2: | 565 | case 2: |
567 | return 9400; | 566 | return 9400; |
568 | case 3: | 567 | case 3: |
569 | return 7800; | 568 | return 7800; |
570 | } | 569 | } |
571 | case 2: | 570 | case 2: |
572 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) | 571 | if (!(data->pin_cfg[1] & ADT7462_PIN22_INPUT)) |
573 | return 62500; | 572 | return 62500; |
574 | break; | 573 | break; |
575 | case 3: | 574 | case 3: |
576 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) | 575 | if (!(data->pin_cfg[1] & ADT7462_PIN21_INPUT)) |
577 | return 26000; | 576 | return 26000; |
578 | break; | 577 | break; |
579 | case 4: | 578 | case 4: |
580 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { | 579 | if (!(data->pin_cfg[0] & ADT7462_DIODE3_INPUT)) { |
581 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) | 580 | if (data->pin_cfg[1] & ADT7462_PIN19_INPUT) |
582 | return 4690; | 581 | return 4690; |
583 | return 6500; | 582 | return 6500; |
584 | } | 583 | } |
585 | break; | 584 | break; |
586 | case 5: | 585 | case 5: |
587 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { | 586 | if (!(data->pin_cfg[0] & ADT7462_DIODE1_INPUT)) { |
588 | if (data->pin_cfg[1] & ADT7462_PIN15_INPUT) | 587 | if (data->pin_cfg[1] & ADT7462_PIN15_INPUT) |
589 | return 9400; | 588 | return 9400; |
590 | return 13000; | 589 | return 13000; |
591 | } | 590 | } |
592 | break; | 591 | break; |
593 | case 6: | 592 | case 6: |
594 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) | 593 | if (!(data->pin_cfg[1] & ADT7462_PIN13_INPUT)) |
595 | return 17200; | 594 | return 17200; |
596 | break; | 595 | break; |
597 | case 7: | 596 | case 7: |
598 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) | 597 | if (!(data->pin_cfg[1] & ADT7462_PIN8_INPUT)) |
599 | return 62500; | 598 | return 62500; |
600 | break; | 599 | break; |
601 | case 8: | 600 | case 8: |
602 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { | 601 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN26)) { |
603 | case 0: | 602 | case 0: |
604 | return 15600; | 603 | return 15600; |
605 | case 1: | 604 | case 1: |
606 | return 6250; | 605 | return 6250; |
607 | } | 606 | } |
608 | break; | 607 | break; |
609 | case 9: | 608 | case 9: |
610 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { | 609 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN25)) { |
611 | case 0: | 610 | case 0: |
612 | return 17200; | 611 | return 17200; |
613 | case 1: | 612 | case 1: |
614 | return 6250; | 613 | return 6250; |
615 | } | 614 | } |
616 | break; | 615 | break; |
617 | case 10: | 616 | case 10: |
618 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { | 617 | switch (MASK_AND_SHIFT(data->pin_cfg[2], ADT7462_PIN24)) { |
619 | case 0: | 618 | case 0: |
620 | return 6250; | 619 | return 6250; |
621 | case 1: | 620 | case 1: |
622 | return 13000; | 621 | return 13000; |
623 | case 2: | 622 | case 2: |
624 | return 9400; | 623 | return 9400; |
625 | case 3: | 624 | case 3: |
626 | return 7800; | 625 | return 7800; |
627 | } | 626 | } |
628 | case 11: | 627 | case 11: |
629 | case 12: | 628 | case 12: |
630 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == | 629 | if (data->pin_cfg[3] >> ADT7462_PIN28_SHIFT == |
631 | ADT7462_PIN28_VOLT && | 630 | ADT7462_PIN28_VOLT && |
632 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) | 631 | !(data->pin_cfg[0] & ADT7462_VID_INPUT)) |
633 | return 7800; | 632 | return 7800; |
634 | } | 633 | } |
635 | return 0; | 634 | return 0; |
636 | } | 635 | } |
637 | 636 | ||
638 | static int temp_enabled(struct adt7462_data *data, int which) | 637 | static int temp_enabled(struct adt7462_data *data, int which) |
639 | { | 638 | { |
640 | switch (which) { | 639 | switch (which) { |
641 | case 0: | 640 | case 0: |
642 | case 2: | 641 | case 2: |
643 | return 1; | 642 | return 1; |
644 | case 1: | 643 | case 1: |
645 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) | 644 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) |
646 | return 1; | 645 | return 1; |
647 | break; | 646 | break; |
648 | case 3: | 647 | case 3: |
649 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) | 648 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) |
650 | return 1; | 649 | return 1; |
651 | break; | 650 | break; |
652 | } | 651 | } |
653 | return 0; | 652 | return 0; |
654 | } | 653 | } |
655 | 654 | ||
656 | static const char *temp_label(struct adt7462_data *data, int which) | 655 | static const char *temp_label(struct adt7462_data *data, int which) |
657 | { | 656 | { |
658 | switch (which) { | 657 | switch (which) { |
659 | case 0: | 658 | case 0: |
660 | return "local"; | 659 | return "local"; |
661 | case 1: | 660 | case 1: |
662 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) | 661 | if (data->pin_cfg[0] & ADT7462_DIODE1_INPUT) |
663 | return "remote1"; | 662 | return "remote1"; |
664 | break; | 663 | break; |
665 | case 2: | 664 | case 2: |
666 | return "remote2"; | 665 | return "remote2"; |
667 | case 3: | 666 | case 3: |
668 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) | 667 | if (data->pin_cfg[0] & ADT7462_DIODE3_INPUT) |
669 | return "remote3"; | 668 | return "remote3"; |
670 | break; | 669 | break; |
671 | } | 670 | } |
672 | return "N/A"; | 671 | return "N/A"; |
673 | } | 672 | } |
674 | 673 | ||
675 | /* Map Trange register values to mC */ | 674 | /* Map Trange register values to mC */ |
676 | #define NUM_TRANGE_VALUES 16 | 675 | #define NUM_TRANGE_VALUES 16 |
677 | static const int trange_values[NUM_TRANGE_VALUES] = { | 676 | static const int trange_values[NUM_TRANGE_VALUES] = { |
678 | 2000, | 677 | 2000, |
679 | 2500, | 678 | 2500, |
680 | 3300, | 679 | 3300, |
681 | 4000, | 680 | 4000, |
682 | 5000, | 681 | 5000, |
683 | 6700, | 682 | 6700, |
684 | 8000, | 683 | 8000, |
685 | 10000, | 684 | 10000, |
686 | 13300, | 685 | 13300, |
687 | 16000, | 686 | 16000, |
688 | 20000, | 687 | 20000, |
689 | 26700, | 688 | 26700, |
690 | 32000, | 689 | 32000, |
691 | 40000, | 690 | 40000, |
692 | 53300, | 691 | 53300, |
693 | 80000 | 692 | 80000 |
694 | }; | 693 | }; |
695 | 694 | ||
696 | static int find_trange_value(int trange) | 695 | static int find_trange_value(int trange) |
697 | { | 696 | { |
698 | int i; | 697 | int i; |
699 | 698 | ||
700 | for (i = 0; i < NUM_TRANGE_VALUES; i++) | 699 | for (i = 0; i < NUM_TRANGE_VALUES; i++) |
701 | if (trange_values[i] == trange) | 700 | if (trange_values[i] == trange) |
702 | return i; | 701 | return i; |
703 | 702 | ||
704 | return -ENODEV; | 703 | return -ENODEV; |
705 | } | 704 | } |
706 | 705 | ||
707 | static struct adt7462_data *adt7462_update_device(struct device *dev) | 706 | static struct adt7462_data *adt7462_update_device(struct device *dev) |
708 | { | 707 | { |
709 | struct i2c_client *client = to_i2c_client(dev); | 708 | struct i2c_client *client = to_i2c_client(dev); |
710 | struct adt7462_data *data = i2c_get_clientdata(client); | 709 | struct adt7462_data *data = i2c_get_clientdata(client); |
711 | unsigned long local_jiffies = jiffies; | 710 | unsigned long local_jiffies = jiffies; |
712 | int i; | 711 | int i; |
713 | 712 | ||
714 | mutex_lock(&data->lock); | 713 | mutex_lock(&data->lock); |
715 | if (time_before(local_jiffies, data->sensors_last_updated + | 714 | if (time_before(local_jiffies, data->sensors_last_updated + |
716 | SENSOR_REFRESH_INTERVAL) | 715 | SENSOR_REFRESH_INTERVAL) |
717 | && data->sensors_valid) | 716 | && data->sensors_valid) |
718 | goto no_sensor_update; | 717 | goto no_sensor_update; |
719 | 718 | ||
720 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { | 719 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { |
721 | /* | 720 | /* |
722 | * Reading the fractional register locks the integral | 721 | * Reading the fractional register locks the integral |
723 | * register until both have been read. | 722 | * register until both have been read. |
724 | */ | 723 | */ |
725 | data->temp_frac[i] = i2c_smbus_read_byte_data(client, | 724 | data->temp_frac[i] = i2c_smbus_read_byte_data(client, |
726 | ADT7462_TEMP_REG(i)); | 725 | ADT7462_TEMP_REG(i)); |
727 | data->temp[i] = i2c_smbus_read_byte_data(client, | 726 | data->temp[i] = i2c_smbus_read_byte_data(client, |
728 | ADT7462_TEMP_REG(i) + 1); | 727 | ADT7462_TEMP_REG(i) + 1); |
729 | } | 728 | } |
730 | 729 | ||
731 | for (i = 0; i < ADT7462_FAN_COUNT; i++) | 730 | for (i = 0; i < ADT7462_FAN_COUNT; i++) |
732 | data->fan[i] = adt7462_read_word_data(client, | 731 | data->fan[i] = adt7462_read_word_data(client, |
733 | ADT7462_REG_FAN(i)); | 732 | ADT7462_REG_FAN(i)); |
734 | 733 | ||
735 | data->fan_enabled = i2c_smbus_read_byte_data(client, | 734 | data->fan_enabled = i2c_smbus_read_byte_data(client, |
736 | ADT7462_REG_FAN_ENABLE); | 735 | ADT7462_REG_FAN_ENABLE); |
737 | 736 | ||
738 | for (i = 0; i < ADT7462_PWM_COUNT; i++) | 737 | for (i = 0; i < ADT7462_PWM_COUNT; i++) |
739 | data->pwm[i] = i2c_smbus_read_byte_data(client, | 738 | data->pwm[i] = i2c_smbus_read_byte_data(client, |
740 | ADT7462_REG_PWM(i)); | 739 | ADT7462_REG_PWM(i)); |
741 | 740 | ||
742 | for (i = 0; i < ADT7462_PIN_CFG_REG_COUNT; i++) | 741 | for (i = 0; i < ADT7462_PIN_CFG_REG_COUNT; i++) |
743 | data->pin_cfg[i] = i2c_smbus_read_byte_data(client, | 742 | data->pin_cfg[i] = i2c_smbus_read_byte_data(client, |
744 | ADT7462_REG_PIN_CFG(i)); | 743 | ADT7462_REG_PIN_CFG(i)); |
745 | 744 | ||
746 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { | 745 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { |
747 | int reg = ADT7462_REG_VOLT(data, i); | 746 | int reg = ADT7462_REG_VOLT(data, i); |
748 | if (!reg) | 747 | if (!reg) |
749 | data->voltages[i] = 0; | 748 | data->voltages[i] = 0; |
750 | else | 749 | else |
751 | data->voltages[i] = i2c_smbus_read_byte_data(client, | 750 | data->voltages[i] = i2c_smbus_read_byte_data(client, |
752 | reg); | 751 | reg); |
753 | } | 752 | } |
754 | 753 | ||
755 | data->alarms[0] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM1); | 754 | data->alarms[0] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM1); |
756 | data->alarms[1] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM2); | 755 | data->alarms[1] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM2); |
757 | data->alarms[2] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM3); | 756 | data->alarms[2] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM3); |
758 | data->alarms[3] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM4); | 757 | data->alarms[3] = i2c_smbus_read_byte_data(client, ADT7462_REG_ALARM4); |
759 | 758 | ||
760 | data->sensors_last_updated = local_jiffies; | 759 | data->sensors_last_updated = local_jiffies; |
761 | data->sensors_valid = 1; | 760 | data->sensors_valid = 1; |
762 | 761 | ||
763 | no_sensor_update: | 762 | no_sensor_update: |
764 | if (time_before(local_jiffies, data->limits_last_updated + | 763 | if (time_before(local_jiffies, data->limits_last_updated + |
765 | LIMIT_REFRESH_INTERVAL) | 764 | LIMIT_REFRESH_INTERVAL) |
766 | && data->limits_valid) | 765 | && data->limits_valid) |
767 | goto out; | 766 | goto out; |
768 | 767 | ||
769 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { | 768 | for (i = 0; i < ADT7462_TEMP_COUNT; i++) { |
770 | data->temp_min[i] = i2c_smbus_read_byte_data(client, | 769 | data->temp_min[i] = i2c_smbus_read_byte_data(client, |
771 | ADT7462_TEMP_MIN_REG(i)); | 770 | ADT7462_TEMP_MIN_REG(i)); |
772 | data->temp_max[i] = i2c_smbus_read_byte_data(client, | 771 | data->temp_max[i] = i2c_smbus_read_byte_data(client, |
773 | ADT7462_TEMP_MAX_REG(i)); | 772 | ADT7462_TEMP_MAX_REG(i)); |
774 | } | 773 | } |
775 | 774 | ||
776 | for (i = 0; i < ADT7462_FAN_COUNT; i++) | 775 | for (i = 0; i < ADT7462_FAN_COUNT; i++) |
777 | data->fan_min[i] = i2c_smbus_read_byte_data(client, | 776 | data->fan_min[i] = i2c_smbus_read_byte_data(client, |
778 | ADT7462_REG_FAN_MIN(i)); | 777 | ADT7462_REG_FAN_MIN(i)); |
779 | 778 | ||
780 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { | 779 | for (i = 0; i < ADT7462_VOLT_COUNT; i++) { |
781 | int reg = ADT7462_REG_VOLT_MAX(data, i); | 780 | int reg = ADT7462_REG_VOLT_MAX(data, i); |
782 | data->volt_max[i] = | 781 | data->volt_max[i] = |
783 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); | 782 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); |
784 | 783 | ||
785 | reg = ADT7462_REG_VOLT_MIN(data, i); | 784 | reg = ADT7462_REG_VOLT_MIN(data, i); |
786 | data->volt_min[i] = | 785 | data->volt_min[i] = |
787 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); | 786 | (reg ? i2c_smbus_read_byte_data(client, reg) : 0); |
788 | } | 787 | } |
789 | 788 | ||
790 | for (i = 0; i < ADT7462_PWM_COUNT; i++) { | 789 | for (i = 0; i < ADT7462_PWM_COUNT; i++) { |
791 | data->pwm_min[i] = i2c_smbus_read_byte_data(client, | 790 | data->pwm_min[i] = i2c_smbus_read_byte_data(client, |
792 | ADT7462_REG_PWM_MIN(i)); | 791 | ADT7462_REG_PWM_MIN(i)); |
793 | data->pwm_tmin[i] = i2c_smbus_read_byte_data(client, | 792 | data->pwm_tmin[i] = i2c_smbus_read_byte_data(client, |
794 | ADT7462_REG_PWM_TMIN(i)); | 793 | ADT7462_REG_PWM_TMIN(i)); |
795 | data->pwm_trange[i] = i2c_smbus_read_byte_data(client, | 794 | data->pwm_trange[i] = i2c_smbus_read_byte_data(client, |
796 | ADT7462_REG_PWM_TRANGE(i)); | 795 | ADT7462_REG_PWM_TRANGE(i)); |
797 | data->pwm_cfg[i] = i2c_smbus_read_byte_data(client, | 796 | data->pwm_cfg[i] = i2c_smbus_read_byte_data(client, |
798 | ADT7462_REG_PWM_CFG(i)); | 797 | ADT7462_REG_PWM_CFG(i)); |
799 | } | 798 | } |
800 | 799 | ||
801 | data->pwm_max = i2c_smbus_read_byte_data(client, ADT7462_REG_PWM_MAX); | 800 | data->pwm_max = i2c_smbus_read_byte_data(client, ADT7462_REG_PWM_MAX); |
802 | 801 | ||
803 | data->cfg2 = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); | 802 | data->cfg2 = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); |
804 | 803 | ||
805 | data->limits_last_updated = local_jiffies; | 804 | data->limits_last_updated = local_jiffies; |
806 | data->limits_valid = 1; | 805 | data->limits_valid = 1; |
807 | 806 | ||
808 | out: | 807 | out: |
809 | mutex_unlock(&data->lock); | 808 | mutex_unlock(&data->lock); |
810 | return data; | 809 | return data; |
811 | } | 810 | } |
812 | 811 | ||
813 | static ssize_t show_temp_min(struct device *dev, | 812 | static ssize_t show_temp_min(struct device *dev, |
814 | struct device_attribute *devattr, | 813 | struct device_attribute *devattr, |
815 | char *buf) | 814 | char *buf) |
816 | { | 815 | { |
817 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 816 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
818 | struct adt7462_data *data = adt7462_update_device(dev); | 817 | struct adt7462_data *data = adt7462_update_device(dev); |
819 | 818 | ||
820 | if (!temp_enabled(data, attr->index)) | 819 | if (!temp_enabled(data, attr->index)) |
821 | return sprintf(buf, "0\n"); | 820 | return sprintf(buf, "0\n"); |
822 | 821 | ||
823 | return sprintf(buf, "%d\n", 1000 * (data->temp_min[attr->index] - 64)); | 822 | return sprintf(buf, "%d\n", 1000 * (data->temp_min[attr->index] - 64)); |
824 | } | 823 | } |
825 | 824 | ||
826 | static ssize_t set_temp_min(struct device *dev, | 825 | static ssize_t set_temp_min(struct device *dev, |
827 | struct device_attribute *devattr, | 826 | struct device_attribute *devattr, |
828 | const char *buf, | 827 | const char *buf, |
829 | size_t count) | 828 | size_t count) |
830 | { | 829 | { |
831 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 830 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
832 | struct i2c_client *client = to_i2c_client(dev); | 831 | struct i2c_client *client = to_i2c_client(dev); |
833 | struct adt7462_data *data = i2c_get_clientdata(client); | 832 | struct adt7462_data *data = i2c_get_clientdata(client); |
834 | long temp; | 833 | long temp; |
835 | 834 | ||
836 | if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | 835 | if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) |
837 | return -EINVAL; | 836 | return -EINVAL; |
838 | 837 | ||
839 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; | 838 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; |
840 | temp = SENSORS_LIMIT(temp, 0, 255); | 839 | temp = SENSORS_LIMIT(temp, 0, 255); |
841 | 840 | ||
842 | mutex_lock(&data->lock); | 841 | mutex_lock(&data->lock); |
843 | data->temp_min[attr->index] = temp; | 842 | data->temp_min[attr->index] = temp; |
844 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MIN_REG(attr->index), | 843 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MIN_REG(attr->index), |
845 | temp); | 844 | temp); |
846 | mutex_unlock(&data->lock); | 845 | mutex_unlock(&data->lock); |
847 | 846 | ||
848 | return count; | 847 | return count; |
849 | } | 848 | } |
850 | 849 | ||
851 | static ssize_t show_temp_max(struct device *dev, | 850 | static ssize_t show_temp_max(struct device *dev, |
852 | struct device_attribute *devattr, | 851 | struct device_attribute *devattr, |
853 | char *buf) | 852 | char *buf) |
854 | { | 853 | { |
855 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 854 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
856 | struct adt7462_data *data = adt7462_update_device(dev); | 855 | struct adt7462_data *data = adt7462_update_device(dev); |
857 | 856 | ||
858 | if (!temp_enabled(data, attr->index)) | 857 | if (!temp_enabled(data, attr->index)) |
859 | return sprintf(buf, "0\n"); | 858 | return sprintf(buf, "0\n"); |
860 | 859 | ||
861 | return sprintf(buf, "%d\n", 1000 * (data->temp_max[attr->index] - 64)); | 860 | return sprintf(buf, "%d\n", 1000 * (data->temp_max[attr->index] - 64)); |
862 | } | 861 | } |
863 | 862 | ||
864 | static ssize_t set_temp_max(struct device *dev, | 863 | static ssize_t set_temp_max(struct device *dev, |
865 | struct device_attribute *devattr, | 864 | struct device_attribute *devattr, |
866 | const char *buf, | 865 | const char *buf, |
867 | size_t count) | 866 | size_t count) |
868 | { | 867 | { |
869 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 868 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
870 | struct i2c_client *client = to_i2c_client(dev); | 869 | struct i2c_client *client = to_i2c_client(dev); |
871 | struct adt7462_data *data = i2c_get_clientdata(client); | 870 | struct adt7462_data *data = i2c_get_clientdata(client); |
872 | long temp; | 871 | long temp; |
873 | 872 | ||
874 | if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) | 873 | if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index)) |
875 | return -EINVAL; | 874 | return -EINVAL; |
876 | 875 | ||
877 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; | 876 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; |
878 | temp = SENSORS_LIMIT(temp, 0, 255); | 877 | temp = SENSORS_LIMIT(temp, 0, 255); |
879 | 878 | ||
880 | mutex_lock(&data->lock); | 879 | mutex_lock(&data->lock); |
881 | data->temp_max[attr->index] = temp; | 880 | data->temp_max[attr->index] = temp; |
882 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MAX_REG(attr->index), | 881 | i2c_smbus_write_byte_data(client, ADT7462_TEMP_MAX_REG(attr->index), |
883 | temp); | 882 | temp); |
884 | mutex_unlock(&data->lock); | 883 | mutex_unlock(&data->lock); |
885 | 884 | ||
886 | return count; | 885 | return count; |
887 | } | 886 | } |
888 | 887 | ||
889 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | 888 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
890 | char *buf) | 889 | char *buf) |
891 | { | 890 | { |
892 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 891 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
893 | struct adt7462_data *data = adt7462_update_device(dev); | 892 | struct adt7462_data *data = adt7462_update_device(dev); |
894 | u8 frac = data->temp_frac[attr->index] >> TEMP_FRAC_OFFSET; | 893 | u8 frac = data->temp_frac[attr->index] >> TEMP_FRAC_OFFSET; |
895 | 894 | ||
896 | if (!temp_enabled(data, attr->index)) | 895 | if (!temp_enabled(data, attr->index)) |
897 | return sprintf(buf, "0\n"); | 896 | return sprintf(buf, "0\n"); |
898 | 897 | ||
899 | return sprintf(buf, "%d\n", 1000 * (data->temp[attr->index] - 64) + | 898 | return sprintf(buf, "%d\n", 1000 * (data->temp[attr->index] - 64) + |
900 | 250 * frac); | 899 | 250 * frac); |
901 | } | 900 | } |
902 | 901 | ||
903 | static ssize_t show_temp_label(struct device *dev, | 902 | static ssize_t show_temp_label(struct device *dev, |
904 | struct device_attribute *devattr, | 903 | struct device_attribute *devattr, |
905 | char *buf) | 904 | char *buf) |
906 | { | 905 | { |
907 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 906 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
908 | struct adt7462_data *data = adt7462_update_device(dev); | 907 | struct adt7462_data *data = adt7462_update_device(dev); |
909 | 908 | ||
910 | return sprintf(buf, "%s\n", temp_label(data, attr->index)); | 909 | return sprintf(buf, "%s\n", temp_label(data, attr->index)); |
911 | } | 910 | } |
912 | 911 | ||
913 | static ssize_t show_volt_max(struct device *dev, | 912 | static ssize_t show_volt_max(struct device *dev, |
914 | struct device_attribute *devattr, | 913 | struct device_attribute *devattr, |
915 | char *buf) | 914 | char *buf) |
916 | { | 915 | { |
917 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 916 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
918 | struct adt7462_data *data = adt7462_update_device(dev); | 917 | struct adt7462_data *data = adt7462_update_device(dev); |
919 | int x = voltage_multiplier(data, attr->index); | 918 | int x = voltage_multiplier(data, attr->index); |
920 | 919 | ||
921 | x *= data->volt_max[attr->index]; | 920 | x *= data->volt_max[attr->index]; |
922 | x /= 1000; /* convert from uV to mV */ | 921 | x /= 1000; /* convert from uV to mV */ |
923 | 922 | ||
924 | return sprintf(buf, "%d\n", x); | 923 | return sprintf(buf, "%d\n", x); |
925 | } | 924 | } |
926 | 925 | ||
927 | static ssize_t set_volt_max(struct device *dev, | 926 | static ssize_t set_volt_max(struct device *dev, |
928 | struct device_attribute *devattr, | 927 | struct device_attribute *devattr, |
929 | const char *buf, | 928 | const char *buf, |
930 | size_t count) | 929 | size_t count) |
931 | { | 930 | { |
932 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 931 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
933 | struct i2c_client *client = to_i2c_client(dev); | 932 | struct i2c_client *client = to_i2c_client(dev); |
934 | struct adt7462_data *data = i2c_get_clientdata(client); | 933 | struct adt7462_data *data = i2c_get_clientdata(client); |
935 | int x = voltage_multiplier(data, attr->index); | 934 | int x = voltage_multiplier(data, attr->index); |
936 | long temp; | 935 | long temp; |
937 | 936 | ||
938 | if (kstrtol(buf, 10, &temp) || !x) | 937 | if (kstrtol(buf, 10, &temp) || !x) |
939 | return -EINVAL; | 938 | return -EINVAL; |
940 | 939 | ||
941 | temp *= 1000; /* convert mV to uV */ | 940 | temp *= 1000; /* convert mV to uV */ |
942 | temp = DIV_ROUND_CLOSEST(temp, x); | 941 | temp = DIV_ROUND_CLOSEST(temp, x); |
943 | temp = SENSORS_LIMIT(temp, 0, 255); | 942 | temp = SENSORS_LIMIT(temp, 0, 255); |
944 | 943 | ||
945 | mutex_lock(&data->lock); | 944 | mutex_lock(&data->lock); |
946 | data->volt_max[attr->index] = temp; | 945 | data->volt_max[attr->index] = temp; |
947 | i2c_smbus_write_byte_data(client, | 946 | i2c_smbus_write_byte_data(client, |
948 | ADT7462_REG_VOLT_MAX(data, attr->index), | 947 | ADT7462_REG_VOLT_MAX(data, attr->index), |
949 | temp); | 948 | temp); |
950 | mutex_unlock(&data->lock); | 949 | mutex_unlock(&data->lock); |
951 | 950 | ||
952 | return count; | 951 | return count; |
953 | } | 952 | } |
954 | 953 | ||
955 | static ssize_t show_volt_min(struct device *dev, | 954 | static ssize_t show_volt_min(struct device *dev, |
956 | struct device_attribute *devattr, | 955 | struct device_attribute *devattr, |
957 | char *buf) | 956 | char *buf) |
958 | { | 957 | { |
959 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 958 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
960 | struct adt7462_data *data = adt7462_update_device(dev); | 959 | struct adt7462_data *data = adt7462_update_device(dev); |
961 | int x = voltage_multiplier(data, attr->index); | 960 | int x = voltage_multiplier(data, attr->index); |
962 | 961 | ||
963 | x *= data->volt_min[attr->index]; | 962 | x *= data->volt_min[attr->index]; |
964 | x /= 1000; /* convert from uV to mV */ | 963 | x /= 1000; /* convert from uV to mV */ |
965 | 964 | ||
966 | return sprintf(buf, "%d\n", x); | 965 | return sprintf(buf, "%d\n", x); |
967 | } | 966 | } |
968 | 967 | ||
969 | static ssize_t set_volt_min(struct device *dev, | 968 | static ssize_t set_volt_min(struct device *dev, |
970 | struct device_attribute *devattr, | 969 | struct device_attribute *devattr, |
971 | const char *buf, | 970 | const char *buf, |
972 | size_t count) | 971 | size_t count) |
973 | { | 972 | { |
974 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 973 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
975 | struct i2c_client *client = to_i2c_client(dev); | 974 | struct i2c_client *client = to_i2c_client(dev); |
976 | struct adt7462_data *data = i2c_get_clientdata(client); | 975 | struct adt7462_data *data = i2c_get_clientdata(client); |
977 | int x = voltage_multiplier(data, attr->index); | 976 | int x = voltage_multiplier(data, attr->index); |
978 | long temp; | 977 | long temp; |
979 | 978 | ||
980 | if (kstrtol(buf, 10, &temp) || !x) | 979 | if (kstrtol(buf, 10, &temp) || !x) |
981 | return -EINVAL; | 980 | return -EINVAL; |
982 | 981 | ||
983 | temp *= 1000; /* convert mV to uV */ | 982 | temp *= 1000; /* convert mV to uV */ |
984 | temp = DIV_ROUND_CLOSEST(temp, x); | 983 | temp = DIV_ROUND_CLOSEST(temp, x); |
985 | temp = SENSORS_LIMIT(temp, 0, 255); | 984 | temp = SENSORS_LIMIT(temp, 0, 255); |
986 | 985 | ||
987 | mutex_lock(&data->lock); | 986 | mutex_lock(&data->lock); |
988 | data->volt_min[attr->index] = temp; | 987 | data->volt_min[attr->index] = temp; |
989 | i2c_smbus_write_byte_data(client, | 988 | i2c_smbus_write_byte_data(client, |
990 | ADT7462_REG_VOLT_MIN(data, attr->index), | 989 | ADT7462_REG_VOLT_MIN(data, attr->index), |
991 | temp); | 990 | temp); |
992 | mutex_unlock(&data->lock); | 991 | mutex_unlock(&data->lock); |
993 | 992 | ||
994 | return count; | 993 | return count; |
995 | } | 994 | } |
996 | 995 | ||
997 | static ssize_t show_voltage(struct device *dev, | 996 | static ssize_t show_voltage(struct device *dev, |
998 | struct device_attribute *devattr, | 997 | struct device_attribute *devattr, |
999 | char *buf) | 998 | char *buf) |
1000 | { | 999 | { |
1001 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1000 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1002 | struct adt7462_data *data = adt7462_update_device(dev); | 1001 | struct adt7462_data *data = adt7462_update_device(dev); |
1003 | int x = voltage_multiplier(data, attr->index); | 1002 | int x = voltage_multiplier(data, attr->index); |
1004 | 1003 | ||
1005 | x *= data->voltages[attr->index]; | 1004 | x *= data->voltages[attr->index]; |
1006 | x /= 1000; /* convert from uV to mV */ | 1005 | x /= 1000; /* convert from uV to mV */ |
1007 | 1006 | ||
1008 | return sprintf(buf, "%d\n", x); | 1007 | return sprintf(buf, "%d\n", x); |
1009 | } | 1008 | } |
1010 | 1009 | ||
1011 | static ssize_t show_voltage_label(struct device *dev, | 1010 | static ssize_t show_voltage_label(struct device *dev, |
1012 | struct device_attribute *devattr, | 1011 | struct device_attribute *devattr, |
1013 | char *buf) | 1012 | char *buf) |
1014 | { | 1013 | { |
1015 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1014 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1016 | struct adt7462_data *data = adt7462_update_device(dev); | 1015 | struct adt7462_data *data = adt7462_update_device(dev); |
1017 | 1016 | ||
1018 | return sprintf(buf, "%s\n", voltage_label(data, attr->index)); | 1017 | return sprintf(buf, "%s\n", voltage_label(data, attr->index)); |
1019 | } | 1018 | } |
1020 | 1019 | ||
1021 | static ssize_t show_alarm(struct device *dev, | 1020 | static ssize_t show_alarm(struct device *dev, |
1022 | struct device_attribute *devattr, | 1021 | struct device_attribute *devattr, |
1023 | char *buf) | 1022 | char *buf) |
1024 | { | 1023 | { |
1025 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1024 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1026 | struct adt7462_data *data = adt7462_update_device(dev); | 1025 | struct adt7462_data *data = adt7462_update_device(dev); |
1027 | int reg = attr->index >> ADT7462_ALARM_REG_SHIFT; | 1026 | int reg = attr->index >> ADT7462_ALARM_REG_SHIFT; |
1028 | int mask = attr->index & ADT7462_ALARM_FLAG_MASK; | 1027 | int mask = attr->index & ADT7462_ALARM_FLAG_MASK; |
1029 | 1028 | ||
1030 | if (data->alarms[reg] & mask) | 1029 | if (data->alarms[reg] & mask) |
1031 | return sprintf(buf, "1\n"); | 1030 | return sprintf(buf, "1\n"); |
1032 | else | 1031 | else |
1033 | return sprintf(buf, "0\n"); | 1032 | return sprintf(buf, "0\n"); |
1034 | } | 1033 | } |
1035 | 1034 | ||
1036 | static int fan_enabled(struct adt7462_data *data, int fan) | 1035 | static int fan_enabled(struct adt7462_data *data, int fan) |
1037 | { | 1036 | { |
1038 | return data->fan_enabled & (1 << fan); | 1037 | return data->fan_enabled & (1 << fan); |
1039 | } | 1038 | } |
1040 | 1039 | ||
1041 | static ssize_t show_fan_min(struct device *dev, | 1040 | static ssize_t show_fan_min(struct device *dev, |
1042 | struct device_attribute *devattr, | 1041 | struct device_attribute *devattr, |
1043 | char *buf) | 1042 | char *buf) |
1044 | { | 1043 | { |
1045 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1044 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1046 | struct adt7462_data *data = adt7462_update_device(dev); | 1045 | struct adt7462_data *data = adt7462_update_device(dev); |
1047 | u16 temp; | 1046 | u16 temp; |
1048 | 1047 | ||
1049 | /* Only the MSB of the min fan period is stored... */ | 1048 | /* Only the MSB of the min fan period is stored... */ |
1050 | temp = data->fan_min[attr->index]; | 1049 | temp = data->fan_min[attr->index]; |
1051 | temp <<= 8; | 1050 | temp <<= 8; |
1052 | 1051 | ||
1053 | if (!fan_enabled(data, attr->index) || | 1052 | if (!fan_enabled(data, attr->index) || |
1054 | !FAN_DATA_VALID(temp)) | 1053 | !FAN_DATA_VALID(temp)) |
1055 | return sprintf(buf, "0\n"); | 1054 | return sprintf(buf, "0\n"); |
1056 | 1055 | ||
1057 | return sprintf(buf, "%d\n", FAN_PERIOD_TO_RPM(temp)); | 1056 | return sprintf(buf, "%d\n", FAN_PERIOD_TO_RPM(temp)); |
1058 | } | 1057 | } |
1059 | 1058 | ||
1060 | static ssize_t set_fan_min(struct device *dev, | 1059 | static ssize_t set_fan_min(struct device *dev, |
1061 | struct device_attribute *devattr, | 1060 | struct device_attribute *devattr, |
1062 | const char *buf, size_t count) | 1061 | const char *buf, size_t count) |
1063 | { | 1062 | { |
1064 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1063 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1065 | struct i2c_client *client = to_i2c_client(dev); | 1064 | struct i2c_client *client = to_i2c_client(dev); |
1066 | struct adt7462_data *data = i2c_get_clientdata(client); | 1065 | struct adt7462_data *data = i2c_get_clientdata(client); |
1067 | long temp; | 1066 | long temp; |
1068 | 1067 | ||
1069 | if (kstrtol(buf, 10, &temp) || !temp || | 1068 | if (kstrtol(buf, 10, &temp) || !temp || |
1070 | !fan_enabled(data, attr->index)) | 1069 | !fan_enabled(data, attr->index)) |
1071 | return -EINVAL; | 1070 | return -EINVAL; |
1072 | 1071 | ||
1073 | temp = FAN_RPM_TO_PERIOD(temp); | 1072 | temp = FAN_RPM_TO_PERIOD(temp); |
1074 | temp >>= 8; | 1073 | temp >>= 8; |
1075 | temp = SENSORS_LIMIT(temp, 1, 255); | 1074 | temp = SENSORS_LIMIT(temp, 1, 255); |
1076 | 1075 | ||
1077 | mutex_lock(&data->lock); | 1076 | mutex_lock(&data->lock); |
1078 | data->fan_min[attr->index] = temp; | 1077 | data->fan_min[attr->index] = temp; |
1079 | i2c_smbus_write_byte_data(client, ADT7462_REG_FAN_MIN(attr->index), | 1078 | i2c_smbus_write_byte_data(client, ADT7462_REG_FAN_MIN(attr->index), |
1080 | temp); | 1079 | temp); |
1081 | mutex_unlock(&data->lock); | 1080 | mutex_unlock(&data->lock); |
1082 | 1081 | ||
1083 | return count; | 1082 | return count; |
1084 | } | 1083 | } |
1085 | 1084 | ||
1086 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | 1085 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, |
1087 | char *buf) | 1086 | char *buf) |
1088 | { | 1087 | { |
1089 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1088 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1090 | struct adt7462_data *data = adt7462_update_device(dev); | 1089 | struct adt7462_data *data = adt7462_update_device(dev); |
1091 | 1090 | ||
1092 | if (!fan_enabled(data, attr->index) || | 1091 | if (!fan_enabled(data, attr->index) || |
1093 | !FAN_DATA_VALID(data->fan[attr->index])) | 1092 | !FAN_DATA_VALID(data->fan[attr->index])) |
1094 | return sprintf(buf, "0\n"); | 1093 | return sprintf(buf, "0\n"); |
1095 | 1094 | ||
1096 | return sprintf(buf, "%d\n", | 1095 | return sprintf(buf, "%d\n", |
1097 | FAN_PERIOD_TO_RPM(data->fan[attr->index])); | 1096 | FAN_PERIOD_TO_RPM(data->fan[attr->index])); |
1098 | } | 1097 | } |
1099 | 1098 | ||
1100 | static ssize_t show_force_pwm_max(struct device *dev, | 1099 | static ssize_t show_force_pwm_max(struct device *dev, |
1101 | struct device_attribute *devattr, | 1100 | struct device_attribute *devattr, |
1102 | char *buf) | 1101 | char *buf) |
1103 | { | 1102 | { |
1104 | struct adt7462_data *data = adt7462_update_device(dev); | 1103 | struct adt7462_data *data = adt7462_update_device(dev); |
1105 | return sprintf(buf, "%d\n", (data->cfg2 & ADT7462_FSPD_MASK ? 1 : 0)); | 1104 | return sprintf(buf, "%d\n", (data->cfg2 & ADT7462_FSPD_MASK ? 1 : 0)); |
1106 | } | 1105 | } |
1107 | 1106 | ||
1108 | static ssize_t set_force_pwm_max(struct device *dev, | 1107 | static ssize_t set_force_pwm_max(struct device *dev, |
1109 | struct device_attribute *devattr, | 1108 | struct device_attribute *devattr, |
1110 | const char *buf, | 1109 | const char *buf, |
1111 | size_t count) | 1110 | size_t count) |
1112 | { | 1111 | { |
1113 | struct i2c_client *client = to_i2c_client(dev); | 1112 | struct i2c_client *client = to_i2c_client(dev); |
1114 | struct adt7462_data *data = i2c_get_clientdata(client); | 1113 | struct adt7462_data *data = i2c_get_clientdata(client); |
1115 | long temp; | 1114 | long temp; |
1116 | u8 reg; | 1115 | u8 reg; |
1117 | 1116 | ||
1118 | if (kstrtol(buf, 10, &temp)) | 1117 | if (kstrtol(buf, 10, &temp)) |
1119 | return -EINVAL; | 1118 | return -EINVAL; |
1120 | 1119 | ||
1121 | mutex_lock(&data->lock); | 1120 | mutex_lock(&data->lock); |
1122 | reg = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); | 1121 | reg = i2c_smbus_read_byte_data(client, ADT7462_REG_CFG2); |
1123 | if (temp) | 1122 | if (temp) |
1124 | reg |= ADT7462_FSPD_MASK; | 1123 | reg |= ADT7462_FSPD_MASK; |
1125 | else | 1124 | else |
1126 | reg &= ~ADT7462_FSPD_MASK; | 1125 | reg &= ~ADT7462_FSPD_MASK; |
1127 | data->cfg2 = reg; | 1126 | data->cfg2 = reg; |
1128 | i2c_smbus_write_byte_data(client, ADT7462_REG_CFG2, reg); | 1127 | i2c_smbus_write_byte_data(client, ADT7462_REG_CFG2, reg); |
1129 | mutex_unlock(&data->lock); | 1128 | mutex_unlock(&data->lock); |
1130 | 1129 | ||
1131 | return count; | 1130 | return count; |
1132 | } | 1131 | } |
1133 | 1132 | ||
1134 | static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, | 1133 | static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, |
1135 | char *buf) | 1134 | char *buf) |
1136 | { | 1135 | { |
1137 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1136 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1138 | struct adt7462_data *data = adt7462_update_device(dev); | 1137 | struct adt7462_data *data = adt7462_update_device(dev); |
1139 | return sprintf(buf, "%d\n", data->pwm[attr->index]); | 1138 | return sprintf(buf, "%d\n", data->pwm[attr->index]); |
1140 | } | 1139 | } |
1141 | 1140 | ||
1142 | static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, | 1141 | static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, |
1143 | const char *buf, size_t count) | 1142 | const char *buf, size_t count) |
1144 | { | 1143 | { |
1145 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1144 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1146 | struct i2c_client *client = to_i2c_client(dev); | 1145 | struct i2c_client *client = to_i2c_client(dev); |
1147 | struct adt7462_data *data = i2c_get_clientdata(client); | 1146 | struct adt7462_data *data = i2c_get_clientdata(client); |
1148 | long temp; | 1147 | long temp; |
1149 | 1148 | ||
1150 | if (kstrtol(buf, 10, &temp)) | 1149 | if (kstrtol(buf, 10, &temp)) |
1151 | return -EINVAL; | 1150 | return -EINVAL; |
1152 | 1151 | ||
1153 | temp = SENSORS_LIMIT(temp, 0, 255); | 1152 | temp = SENSORS_LIMIT(temp, 0, 255); |
1154 | 1153 | ||
1155 | mutex_lock(&data->lock); | 1154 | mutex_lock(&data->lock); |
1156 | data->pwm[attr->index] = temp; | 1155 | data->pwm[attr->index] = temp; |
1157 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM(attr->index), temp); | 1156 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM(attr->index), temp); |
1158 | mutex_unlock(&data->lock); | 1157 | mutex_unlock(&data->lock); |
1159 | 1158 | ||
1160 | return count; | 1159 | return count; |
1161 | } | 1160 | } |
1162 | 1161 | ||
1163 | static ssize_t show_pwm_max(struct device *dev, | 1162 | static ssize_t show_pwm_max(struct device *dev, |
1164 | struct device_attribute *devattr, | 1163 | struct device_attribute *devattr, |
1165 | char *buf) | 1164 | char *buf) |
1166 | { | 1165 | { |
1167 | struct adt7462_data *data = adt7462_update_device(dev); | 1166 | struct adt7462_data *data = adt7462_update_device(dev); |
1168 | return sprintf(buf, "%d\n", data->pwm_max); | 1167 | return sprintf(buf, "%d\n", data->pwm_max); |
1169 | } | 1168 | } |
1170 | 1169 | ||
1171 | static ssize_t set_pwm_max(struct device *dev, | 1170 | static ssize_t set_pwm_max(struct device *dev, |
1172 | struct device_attribute *devattr, | 1171 | struct device_attribute *devattr, |
1173 | const char *buf, | 1172 | const char *buf, |
1174 | size_t count) | 1173 | size_t count) |
1175 | { | 1174 | { |
1176 | struct i2c_client *client = to_i2c_client(dev); | 1175 | struct i2c_client *client = to_i2c_client(dev); |
1177 | struct adt7462_data *data = i2c_get_clientdata(client); | 1176 | struct adt7462_data *data = i2c_get_clientdata(client); |
1178 | long temp; | 1177 | long temp; |
1179 | 1178 | ||
1180 | if (kstrtol(buf, 10, &temp)) | 1179 | if (kstrtol(buf, 10, &temp)) |
1181 | return -EINVAL; | 1180 | return -EINVAL; |
1182 | 1181 | ||
1183 | temp = SENSORS_LIMIT(temp, 0, 255); | 1182 | temp = SENSORS_LIMIT(temp, 0, 255); |
1184 | 1183 | ||
1185 | mutex_lock(&data->lock); | 1184 | mutex_lock(&data->lock); |
1186 | data->pwm_max = temp; | 1185 | data->pwm_max = temp; |
1187 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MAX, temp); | 1186 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MAX, temp); |
1188 | mutex_unlock(&data->lock); | 1187 | mutex_unlock(&data->lock); |
1189 | 1188 | ||
1190 | return count; | 1189 | return count; |
1191 | } | 1190 | } |
1192 | 1191 | ||
1193 | static ssize_t show_pwm_min(struct device *dev, | 1192 | static ssize_t show_pwm_min(struct device *dev, |
1194 | struct device_attribute *devattr, | 1193 | struct device_attribute *devattr, |
1195 | char *buf) | 1194 | char *buf) |
1196 | { | 1195 | { |
1197 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1196 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1198 | struct adt7462_data *data = adt7462_update_device(dev); | 1197 | struct adt7462_data *data = adt7462_update_device(dev); |
1199 | return sprintf(buf, "%d\n", data->pwm_min[attr->index]); | 1198 | return sprintf(buf, "%d\n", data->pwm_min[attr->index]); |
1200 | } | 1199 | } |
1201 | 1200 | ||
1202 | static ssize_t set_pwm_min(struct device *dev, | 1201 | static ssize_t set_pwm_min(struct device *dev, |
1203 | struct device_attribute *devattr, | 1202 | struct device_attribute *devattr, |
1204 | const char *buf, | 1203 | const char *buf, |
1205 | size_t count) | 1204 | size_t count) |
1206 | { | 1205 | { |
1207 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1206 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1208 | struct i2c_client *client = to_i2c_client(dev); | 1207 | struct i2c_client *client = to_i2c_client(dev); |
1209 | struct adt7462_data *data = i2c_get_clientdata(client); | 1208 | struct adt7462_data *data = i2c_get_clientdata(client); |
1210 | long temp; | 1209 | long temp; |
1211 | 1210 | ||
1212 | if (kstrtol(buf, 10, &temp)) | 1211 | if (kstrtol(buf, 10, &temp)) |
1213 | return -EINVAL; | 1212 | return -EINVAL; |
1214 | 1213 | ||
1215 | temp = SENSORS_LIMIT(temp, 0, 255); | 1214 | temp = SENSORS_LIMIT(temp, 0, 255); |
1216 | 1215 | ||
1217 | mutex_lock(&data->lock); | 1216 | mutex_lock(&data->lock); |
1218 | data->pwm_min[attr->index] = temp; | 1217 | data->pwm_min[attr->index] = temp; |
1219 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MIN(attr->index), | 1218 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_MIN(attr->index), |
1220 | temp); | 1219 | temp); |
1221 | mutex_unlock(&data->lock); | 1220 | mutex_unlock(&data->lock); |
1222 | 1221 | ||
1223 | return count; | 1222 | return count; |
1224 | } | 1223 | } |
1225 | 1224 | ||
1226 | static ssize_t show_pwm_hyst(struct device *dev, | 1225 | static ssize_t show_pwm_hyst(struct device *dev, |
1227 | struct device_attribute *devattr, | 1226 | struct device_attribute *devattr, |
1228 | char *buf) | 1227 | char *buf) |
1229 | { | 1228 | { |
1230 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1229 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1231 | struct adt7462_data *data = adt7462_update_device(dev); | 1230 | struct adt7462_data *data = adt7462_update_device(dev); |
1232 | return sprintf(buf, "%d\n", 1000 * | 1231 | return sprintf(buf, "%d\n", 1000 * |
1233 | (data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK)); | 1232 | (data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK)); |
1234 | } | 1233 | } |
1235 | 1234 | ||
1236 | static ssize_t set_pwm_hyst(struct device *dev, | 1235 | static ssize_t set_pwm_hyst(struct device *dev, |
1237 | struct device_attribute *devattr, | 1236 | struct device_attribute *devattr, |
1238 | const char *buf, | 1237 | const char *buf, |
1239 | size_t count) | 1238 | size_t count) |
1240 | { | 1239 | { |
1241 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1240 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1242 | struct i2c_client *client = to_i2c_client(dev); | 1241 | struct i2c_client *client = to_i2c_client(dev); |
1243 | struct adt7462_data *data = i2c_get_clientdata(client); | 1242 | struct adt7462_data *data = i2c_get_clientdata(client); |
1244 | long temp; | 1243 | long temp; |
1245 | 1244 | ||
1246 | if (kstrtol(buf, 10, &temp)) | 1245 | if (kstrtol(buf, 10, &temp)) |
1247 | return -EINVAL; | 1246 | return -EINVAL; |
1248 | 1247 | ||
1249 | temp = DIV_ROUND_CLOSEST(temp, 1000); | 1248 | temp = DIV_ROUND_CLOSEST(temp, 1000); |
1250 | temp = SENSORS_LIMIT(temp, 0, 15); | 1249 | temp = SENSORS_LIMIT(temp, 0, 15); |
1251 | 1250 | ||
1252 | /* package things up */ | 1251 | /* package things up */ |
1253 | temp &= ADT7462_PWM_HYST_MASK; | 1252 | temp &= ADT7462_PWM_HYST_MASK; |
1254 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_RANGE_MASK; | 1253 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_RANGE_MASK; |
1255 | 1254 | ||
1256 | mutex_lock(&data->lock); | 1255 | mutex_lock(&data->lock); |
1257 | data->pwm_trange[attr->index] = temp; | 1256 | data->pwm_trange[attr->index] = temp; |
1258 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), | 1257 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), |
1259 | temp); | 1258 | temp); |
1260 | mutex_unlock(&data->lock); | 1259 | mutex_unlock(&data->lock); |
1261 | 1260 | ||
1262 | return count; | 1261 | return count; |
1263 | } | 1262 | } |
1264 | 1263 | ||
1265 | static ssize_t show_pwm_tmax(struct device *dev, | 1264 | static ssize_t show_pwm_tmax(struct device *dev, |
1266 | struct device_attribute *devattr, | 1265 | struct device_attribute *devattr, |
1267 | char *buf) | 1266 | char *buf) |
1268 | { | 1267 | { |
1269 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1268 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1270 | struct adt7462_data *data = adt7462_update_device(dev); | 1269 | struct adt7462_data *data = adt7462_update_device(dev); |
1271 | 1270 | ||
1272 | /* tmax = tmin + trange */ | 1271 | /* tmax = tmin + trange */ |
1273 | int trange = trange_values[data->pwm_trange[attr->index] >> | 1272 | int trange = trange_values[data->pwm_trange[attr->index] >> |
1274 | ADT7462_PWM_RANGE_SHIFT]; | 1273 | ADT7462_PWM_RANGE_SHIFT]; |
1275 | int tmin = (data->pwm_tmin[attr->index] - 64) * 1000; | 1274 | int tmin = (data->pwm_tmin[attr->index] - 64) * 1000; |
1276 | 1275 | ||
1277 | return sprintf(buf, "%d\n", tmin + trange); | 1276 | return sprintf(buf, "%d\n", tmin + trange); |
1278 | } | 1277 | } |
1279 | 1278 | ||
1280 | static ssize_t set_pwm_tmax(struct device *dev, | 1279 | static ssize_t set_pwm_tmax(struct device *dev, |
1281 | struct device_attribute *devattr, | 1280 | struct device_attribute *devattr, |
1282 | const char *buf, | 1281 | const char *buf, |
1283 | size_t count) | 1282 | size_t count) |
1284 | { | 1283 | { |
1285 | int temp; | 1284 | int temp; |
1286 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1285 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1287 | struct i2c_client *client = to_i2c_client(dev); | 1286 | struct i2c_client *client = to_i2c_client(dev); |
1288 | struct adt7462_data *data = i2c_get_clientdata(client); | 1287 | struct adt7462_data *data = i2c_get_clientdata(client); |
1289 | int tmin, trange_value; | 1288 | int tmin, trange_value; |
1290 | long trange; | 1289 | long trange; |
1291 | 1290 | ||
1292 | if (kstrtol(buf, 10, &trange)) | 1291 | if (kstrtol(buf, 10, &trange)) |
1293 | return -EINVAL; | 1292 | return -EINVAL; |
1294 | 1293 | ||
1295 | /* trange = tmax - tmin */ | 1294 | /* trange = tmax - tmin */ |
1296 | tmin = (data->pwm_tmin[attr->index] - 64) * 1000; | 1295 | tmin = (data->pwm_tmin[attr->index] - 64) * 1000; |
1297 | trange_value = find_trange_value(trange - tmin); | 1296 | trange_value = find_trange_value(trange - tmin); |
1298 | 1297 | ||
1299 | if (trange_value < 0) | 1298 | if (trange_value < 0) |
1300 | return -EINVAL; | 1299 | return -EINVAL; |
1301 | 1300 | ||
1302 | temp = trange_value << ADT7462_PWM_RANGE_SHIFT; | 1301 | temp = trange_value << ADT7462_PWM_RANGE_SHIFT; |
1303 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK; | 1302 | temp |= data->pwm_trange[attr->index] & ADT7462_PWM_HYST_MASK; |
1304 | 1303 | ||
1305 | mutex_lock(&data->lock); | 1304 | mutex_lock(&data->lock); |
1306 | data->pwm_trange[attr->index] = temp; | 1305 | data->pwm_trange[attr->index] = temp; |
1307 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), | 1306 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TRANGE(attr->index), |
1308 | temp); | 1307 | temp); |
1309 | mutex_unlock(&data->lock); | 1308 | mutex_unlock(&data->lock); |
1310 | 1309 | ||
1311 | return count; | 1310 | return count; |
1312 | } | 1311 | } |
1313 | 1312 | ||
1314 | static ssize_t show_pwm_tmin(struct device *dev, | 1313 | static ssize_t show_pwm_tmin(struct device *dev, |
1315 | struct device_attribute *devattr, | 1314 | struct device_attribute *devattr, |
1316 | char *buf) | 1315 | char *buf) |
1317 | { | 1316 | { |
1318 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1317 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1319 | struct adt7462_data *data = adt7462_update_device(dev); | 1318 | struct adt7462_data *data = adt7462_update_device(dev); |
1320 | return sprintf(buf, "%d\n", 1000 * (data->pwm_tmin[attr->index] - 64)); | 1319 | return sprintf(buf, "%d\n", 1000 * (data->pwm_tmin[attr->index] - 64)); |
1321 | } | 1320 | } |
1322 | 1321 | ||
1323 | static ssize_t set_pwm_tmin(struct device *dev, | 1322 | static ssize_t set_pwm_tmin(struct device *dev, |
1324 | struct device_attribute *devattr, | 1323 | struct device_attribute *devattr, |
1325 | const char *buf, | 1324 | const char *buf, |
1326 | size_t count) | 1325 | size_t count) |
1327 | { | 1326 | { |
1328 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1327 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1329 | struct i2c_client *client = to_i2c_client(dev); | 1328 | struct i2c_client *client = to_i2c_client(dev); |
1330 | struct adt7462_data *data = i2c_get_clientdata(client); | 1329 | struct adt7462_data *data = i2c_get_clientdata(client); |
1331 | long temp; | 1330 | long temp; |
1332 | 1331 | ||
1333 | if (kstrtol(buf, 10, &temp)) | 1332 | if (kstrtol(buf, 10, &temp)) |
1334 | return -EINVAL; | 1333 | return -EINVAL; |
1335 | 1334 | ||
1336 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; | 1335 | temp = DIV_ROUND_CLOSEST(temp, 1000) + 64; |
1337 | temp = SENSORS_LIMIT(temp, 0, 255); | 1336 | temp = SENSORS_LIMIT(temp, 0, 255); |
1338 | 1337 | ||
1339 | mutex_lock(&data->lock); | 1338 | mutex_lock(&data->lock); |
1340 | data->pwm_tmin[attr->index] = temp; | 1339 | data->pwm_tmin[attr->index] = temp; |
1341 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TMIN(attr->index), | 1340 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_TMIN(attr->index), |
1342 | temp); | 1341 | temp); |
1343 | mutex_unlock(&data->lock); | 1342 | mutex_unlock(&data->lock); |
1344 | 1343 | ||
1345 | return count; | 1344 | return count; |
1346 | } | 1345 | } |
1347 | 1346 | ||
1348 | static ssize_t show_pwm_auto(struct device *dev, | 1347 | static ssize_t show_pwm_auto(struct device *dev, |
1349 | struct device_attribute *devattr, | 1348 | struct device_attribute *devattr, |
1350 | char *buf) | 1349 | char *buf) |
1351 | { | 1350 | { |
1352 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1351 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1353 | struct adt7462_data *data = adt7462_update_device(dev); | 1352 | struct adt7462_data *data = adt7462_update_device(dev); |
1354 | int cfg = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; | 1353 | int cfg = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; |
1355 | 1354 | ||
1356 | switch (cfg) { | 1355 | switch (cfg) { |
1357 | case 4: /* off */ | 1356 | case 4: /* off */ |
1358 | return sprintf(buf, "0\n"); | 1357 | return sprintf(buf, "0\n"); |
1359 | case 7: /* manual */ | 1358 | case 7: /* manual */ |
1360 | return sprintf(buf, "1\n"); | 1359 | return sprintf(buf, "1\n"); |
1361 | default: /* automatic */ | 1360 | default: /* automatic */ |
1362 | return sprintf(buf, "2\n"); | 1361 | return sprintf(buf, "2\n"); |
1363 | } | 1362 | } |
1364 | } | 1363 | } |
1365 | 1364 | ||
1366 | static void set_pwm_channel(struct i2c_client *client, | 1365 | static void set_pwm_channel(struct i2c_client *client, |
1367 | struct adt7462_data *data, | 1366 | struct adt7462_data *data, |
1368 | int which, | 1367 | int which, |
1369 | int value) | 1368 | int value) |
1370 | { | 1369 | { |
1371 | int temp = data->pwm_cfg[which] & ~ADT7462_PWM_CHANNEL_MASK; | 1370 | int temp = data->pwm_cfg[which] & ~ADT7462_PWM_CHANNEL_MASK; |
1372 | temp |= value << ADT7462_PWM_CHANNEL_SHIFT; | 1371 | temp |= value << ADT7462_PWM_CHANNEL_SHIFT; |
1373 | 1372 | ||
1374 | mutex_lock(&data->lock); | 1373 | mutex_lock(&data->lock); |
1375 | data->pwm_cfg[which] = temp; | 1374 | data->pwm_cfg[which] = temp; |
1376 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_CFG(which), temp); | 1375 | i2c_smbus_write_byte_data(client, ADT7462_REG_PWM_CFG(which), temp); |
1377 | mutex_unlock(&data->lock); | 1376 | mutex_unlock(&data->lock); |
1378 | } | 1377 | } |
1379 | 1378 | ||
1380 | static ssize_t set_pwm_auto(struct device *dev, | 1379 | static ssize_t set_pwm_auto(struct device *dev, |
1381 | struct device_attribute *devattr, | 1380 | struct device_attribute *devattr, |
1382 | const char *buf, | 1381 | const char *buf, |
1383 | size_t count) | 1382 | size_t count) |
1384 | { | 1383 | { |
1385 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1384 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1386 | struct i2c_client *client = to_i2c_client(dev); | 1385 | struct i2c_client *client = to_i2c_client(dev); |
1387 | struct adt7462_data *data = i2c_get_clientdata(client); | 1386 | struct adt7462_data *data = i2c_get_clientdata(client); |
1388 | long temp; | 1387 | long temp; |
1389 | 1388 | ||
1390 | if (kstrtol(buf, 10, &temp)) | 1389 | if (kstrtol(buf, 10, &temp)) |
1391 | return -EINVAL; | 1390 | return -EINVAL; |
1392 | 1391 | ||
1393 | switch (temp) { | 1392 | switch (temp) { |
1394 | case 0: /* off */ | 1393 | case 0: /* off */ |
1395 | set_pwm_channel(client, data, attr->index, 4); | 1394 | set_pwm_channel(client, data, attr->index, 4); |
1396 | return count; | 1395 | return count; |
1397 | case 1: /* manual */ | 1396 | case 1: /* manual */ |
1398 | set_pwm_channel(client, data, attr->index, 7); | 1397 | set_pwm_channel(client, data, attr->index, 7); |
1399 | return count; | 1398 | return count; |
1400 | default: | 1399 | default: |
1401 | return -EINVAL; | 1400 | return -EINVAL; |
1402 | } | 1401 | } |
1403 | } | 1402 | } |
1404 | 1403 | ||
1405 | static ssize_t show_pwm_auto_temp(struct device *dev, | 1404 | static ssize_t show_pwm_auto_temp(struct device *dev, |
1406 | struct device_attribute *devattr, | 1405 | struct device_attribute *devattr, |
1407 | char *buf) | 1406 | char *buf) |
1408 | { | 1407 | { |
1409 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1408 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1410 | struct adt7462_data *data = adt7462_update_device(dev); | 1409 | struct adt7462_data *data = adt7462_update_device(dev); |
1411 | int channel = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; | 1410 | int channel = data->pwm_cfg[attr->index] >> ADT7462_PWM_CHANNEL_SHIFT; |
1412 | 1411 | ||
1413 | switch (channel) { | 1412 | switch (channel) { |
1414 | case 0: /* temp[1234] only */ | 1413 | case 0: /* temp[1234] only */ |
1415 | case 1: | 1414 | case 1: |
1416 | case 2: | 1415 | case 2: |
1417 | case 3: | 1416 | case 3: |
1418 | return sprintf(buf, "%d\n", (1 << channel)); | 1417 | return sprintf(buf, "%d\n", (1 << channel)); |
1419 | case 5: /* temp1 & temp4 */ | 1418 | case 5: /* temp1 & temp4 */ |
1420 | return sprintf(buf, "9\n"); | 1419 | return sprintf(buf, "9\n"); |
1421 | case 6: | 1420 | case 6: |
1422 | return sprintf(buf, "15\n"); | 1421 | return sprintf(buf, "15\n"); |
1423 | default: | 1422 | default: |
1424 | return sprintf(buf, "0\n"); | 1423 | return sprintf(buf, "0\n"); |
1425 | } | 1424 | } |
1426 | } | 1425 | } |
1427 | 1426 | ||
1428 | static int cvt_auto_temp(int input) | 1427 | static int cvt_auto_temp(int input) |
1429 | { | 1428 | { |
1430 | if (input == 0xF) | 1429 | if (input == 0xF) |
1431 | return 6; | 1430 | return 6; |
1432 | if (input == 0x9) | 1431 | if (input == 0x9) |
1433 | return 5; | 1432 | return 5; |
1434 | if (input < 1 || !is_power_of_2(input)) | 1433 | if (input < 1 || !is_power_of_2(input)) |
1435 | return -EINVAL; | 1434 | return -EINVAL; |
1436 | return ilog2(input); | 1435 | return ilog2(input); |
1437 | } | 1436 | } |
1438 | 1437 | ||
1439 | static ssize_t set_pwm_auto_temp(struct device *dev, | 1438 | static ssize_t set_pwm_auto_temp(struct device *dev, |
1440 | struct device_attribute *devattr, | 1439 | struct device_attribute *devattr, |
1441 | const char *buf, | 1440 | const char *buf, |
1442 | size_t count) | 1441 | size_t count) |
1443 | { | 1442 | { |
1444 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 1443 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
1445 | struct i2c_client *client = to_i2c_client(dev); | 1444 | struct i2c_client *client = to_i2c_client(dev); |
1446 | struct adt7462_data *data = i2c_get_clientdata(client); | 1445 | struct adt7462_data *data = i2c_get_clientdata(client); |
1447 | long temp; | 1446 | long temp; |
1448 | 1447 | ||
1449 | if (kstrtol(buf, 10, &temp)) | 1448 | if (kstrtol(buf, 10, &temp)) |
1450 | return -EINVAL; | 1449 | return -EINVAL; |
1451 | 1450 | ||
1452 | temp = cvt_auto_temp(temp); | 1451 | temp = cvt_auto_temp(temp); |
1453 | if (temp < 0) | 1452 | if (temp < 0) |
1454 | return temp; | 1453 | return temp; |
1455 | 1454 | ||
1456 | set_pwm_channel(client, data, attr->index, temp); | 1455 | set_pwm_channel(client, data, attr->index, temp); |
1457 | 1456 | ||
1458 | return count; | 1457 | return count; |
1459 | } | 1458 | } |
1460 | 1459 | ||
1461 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, | 1460 | static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max, |
1462 | set_temp_max, 0); | 1461 | set_temp_max, 0); |
1463 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, | 1462 | static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max, |
1464 | set_temp_max, 1); | 1463 | set_temp_max, 1); |
1465 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, | 1464 | static SENSOR_DEVICE_ATTR(temp3_max, S_IWUSR | S_IRUGO, show_temp_max, |
1466 | set_temp_max, 2); | 1465 | set_temp_max, 2); |
1467 | static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, | 1466 | static SENSOR_DEVICE_ATTR(temp4_max, S_IWUSR | S_IRUGO, show_temp_max, |
1468 | set_temp_max, 3); | 1467 | set_temp_max, 3); |
1469 | 1468 | ||
1470 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, | 1469 | static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min, |
1471 | set_temp_min, 0); | 1470 | set_temp_min, 0); |
1472 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, | 1471 | static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min, |
1473 | set_temp_min, 1); | 1472 | set_temp_min, 1); |
1474 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, | 1473 | static SENSOR_DEVICE_ATTR(temp3_min, S_IWUSR | S_IRUGO, show_temp_min, |
1475 | set_temp_min, 2); | 1474 | set_temp_min, 2); |
1476 | static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min, | 1475 | static SENSOR_DEVICE_ATTR(temp4_min, S_IWUSR | S_IRUGO, show_temp_min, |
1477 | set_temp_min, 3); | 1476 | set_temp_min, 3); |
1478 | 1477 | ||
1479 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); | 1478 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0); |
1480 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); | 1479 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1); |
1481 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); | 1480 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2); |
1482 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); | 1481 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp, NULL, 3); |
1483 | 1482 | ||
1484 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0); | 1483 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, show_temp_label, NULL, 0); |
1485 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1); | 1484 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_temp_label, NULL, 1); |
1486 | static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2); | 1485 | static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, show_temp_label, NULL, 2); |
1487 | static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3); | 1486 | static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, show_temp_label, NULL, 3); |
1488 | 1487 | ||
1489 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, | 1488 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, |
1490 | ADT7462_ALARM1 | ADT7462_LT_ALARM); | 1489 | ADT7462_ALARM1 | ADT7462_LT_ALARM); |
1491 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, | 1490 | static SENSOR_DEVICE_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, |
1492 | ADT7462_ALARM1 | ADT7462_R1T_ALARM); | 1491 | ADT7462_ALARM1 | ADT7462_R1T_ALARM); |
1493 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, | 1492 | static SENSOR_DEVICE_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, |
1494 | ADT7462_ALARM1 | ADT7462_R2T_ALARM); | 1493 | ADT7462_ALARM1 | ADT7462_R2T_ALARM); |
1495 | static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, | 1494 | static SENSOR_DEVICE_ATTR(temp4_alarm, S_IRUGO, show_alarm, NULL, |
1496 | ADT7462_ALARM1 | ADT7462_R3T_ALARM); | 1495 | ADT7462_ALARM1 | ADT7462_R3T_ALARM); |
1497 | 1496 | ||
1498 | static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max, | 1497 | static SENSOR_DEVICE_ATTR(in1_max, S_IWUSR | S_IRUGO, show_volt_max, |
1499 | set_volt_max, 0); | 1498 | set_volt_max, 0); |
1500 | static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max, | 1499 | static SENSOR_DEVICE_ATTR(in2_max, S_IWUSR | S_IRUGO, show_volt_max, |
1501 | set_volt_max, 1); | 1500 | set_volt_max, 1); |
1502 | static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_volt_max, | 1501 | static SENSOR_DEVICE_ATTR(in3_max, S_IWUSR | S_IRUGO, show_volt_max, |
1503 | set_volt_max, 2); | 1502 | set_volt_max, 2); |
1504 | static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_volt_max, | 1503 | static SENSOR_DEVICE_ATTR(in4_max, S_IWUSR | S_IRUGO, show_volt_max, |
1505 | set_volt_max, 3); | 1504 | set_volt_max, 3); |
1506 | static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_volt_max, | 1505 | static SENSOR_DEVICE_ATTR(in5_max, S_IWUSR | S_IRUGO, show_volt_max, |
1507 | set_volt_max, 4); | 1506 | set_volt_max, 4); |
1508 | static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_volt_max, | 1507 | static SENSOR_DEVICE_ATTR(in6_max, S_IWUSR | S_IRUGO, show_volt_max, |
1509 | set_volt_max, 5); | 1508 | set_volt_max, 5); |
1510 | static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, show_volt_max, | 1509 | static SENSOR_DEVICE_ATTR(in7_max, S_IWUSR | S_IRUGO, show_volt_max, |
1511 | set_volt_max, 6); | 1510 | set_volt_max, 6); |
1512 | static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, show_volt_max, | 1511 | static SENSOR_DEVICE_ATTR(in8_max, S_IWUSR | S_IRUGO, show_volt_max, |
1513 | set_volt_max, 7); | 1512 | set_volt_max, 7); |
1514 | static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, show_volt_max, | 1513 | static SENSOR_DEVICE_ATTR(in9_max, S_IWUSR | S_IRUGO, show_volt_max, |
1515 | set_volt_max, 8); | 1514 | set_volt_max, 8); |
1516 | static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, show_volt_max, | 1515 | static SENSOR_DEVICE_ATTR(in10_max, S_IWUSR | S_IRUGO, show_volt_max, |
1517 | set_volt_max, 9); | 1516 | set_volt_max, 9); |
1518 | static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, show_volt_max, | 1517 | static SENSOR_DEVICE_ATTR(in11_max, S_IWUSR | S_IRUGO, show_volt_max, |
1519 | set_volt_max, 10); | 1518 | set_volt_max, 10); |
1520 | static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, show_volt_max, | 1519 | static SENSOR_DEVICE_ATTR(in12_max, S_IWUSR | S_IRUGO, show_volt_max, |
1521 | set_volt_max, 11); | 1520 | set_volt_max, 11); |
1522 | static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, show_volt_max, | 1521 | static SENSOR_DEVICE_ATTR(in13_max, S_IWUSR | S_IRUGO, show_volt_max, |
1523 | set_volt_max, 12); | 1522 | set_volt_max, 12); |
1524 | 1523 | ||
1525 | static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min, | 1524 | static SENSOR_DEVICE_ATTR(in1_min, S_IWUSR | S_IRUGO, show_volt_min, |
1526 | set_volt_min, 0); | 1525 | set_volt_min, 0); |
1527 | static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min, | 1526 | static SENSOR_DEVICE_ATTR(in2_min, S_IWUSR | S_IRUGO, show_volt_min, |
1528 | set_volt_min, 1); | 1527 | set_volt_min, 1); |
1529 | static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_volt_min, | 1528 | static SENSOR_DEVICE_ATTR(in3_min, S_IWUSR | S_IRUGO, show_volt_min, |
1530 | set_volt_min, 2); | 1529 | set_volt_min, 2); |
1531 | static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_volt_min, | 1530 | static SENSOR_DEVICE_ATTR(in4_min, S_IWUSR | S_IRUGO, show_volt_min, |
1532 | set_volt_min, 3); | 1531 | set_volt_min, 3); |
1533 | static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_volt_min, | 1532 | static SENSOR_DEVICE_ATTR(in5_min, S_IWUSR | S_IRUGO, show_volt_min, |
1534 | set_volt_min, 4); | 1533 | set_volt_min, 4); |
1535 | static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_volt_min, | 1534 | static SENSOR_DEVICE_ATTR(in6_min, S_IWUSR | S_IRUGO, show_volt_min, |
1536 | set_volt_min, 5); | 1535 | set_volt_min, 5); |
1537 | static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, show_volt_min, | 1536 | static SENSOR_DEVICE_ATTR(in7_min, S_IWUSR | S_IRUGO, show_volt_min, |
1538 | set_volt_min, 6); | 1537 | set_volt_min, 6); |
1539 | static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, show_volt_min, | 1538 | static SENSOR_DEVICE_ATTR(in8_min, S_IWUSR | S_IRUGO, show_volt_min, |
1540 | set_volt_min, 7); | 1539 | set_volt_min, 7); |
1541 | static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, show_volt_min, | 1540 | static SENSOR_DEVICE_ATTR(in9_min, S_IWUSR | S_IRUGO, show_volt_min, |
1542 | set_volt_min, 8); | 1541 | set_volt_min, 8); |
1543 | static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, show_volt_min, | 1542 | static SENSOR_DEVICE_ATTR(in10_min, S_IWUSR | S_IRUGO, show_volt_min, |
1544 | set_volt_min, 9); | 1543 | set_volt_min, 9); |
1545 | static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, show_volt_min, | 1544 | static SENSOR_DEVICE_ATTR(in11_min, S_IWUSR | S_IRUGO, show_volt_min, |
1546 | set_volt_min, 10); | 1545 | set_volt_min, 10); |
1547 | static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, show_volt_min, | 1546 | static SENSOR_DEVICE_ATTR(in12_min, S_IWUSR | S_IRUGO, show_volt_min, |
1548 | set_volt_min, 11); | 1547 | set_volt_min, 11); |
1549 | static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, show_volt_min, | 1548 | static SENSOR_DEVICE_ATTR(in13_min, S_IWUSR | S_IRUGO, show_volt_min, |
1550 | set_volt_min, 12); | 1549 | set_volt_min, 12); |
1551 | 1550 | ||
1552 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); | 1551 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, show_voltage, NULL, 0); |
1553 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); | 1552 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_voltage, NULL, 1); |
1554 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); | 1553 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_voltage, NULL, 2); |
1555 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); | 1554 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_voltage, NULL, 3); |
1556 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); | 1555 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, show_voltage, NULL, 4); |
1557 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); | 1556 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, show_voltage, NULL, 5); |
1558 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); | 1557 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, show_voltage, NULL, 6); |
1559 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); | 1558 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, show_voltage, NULL, 7); |
1560 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); | 1559 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, show_voltage, NULL, 8); |
1561 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); | 1560 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, show_voltage, NULL, 9); |
1562 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); | 1561 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, show_voltage, NULL, 10); |
1563 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); | 1562 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, show_voltage, NULL, 11); |
1564 | static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); | 1563 | static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, show_voltage, NULL, 12); |
1565 | 1564 | ||
1566 | static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0); | 1565 | static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, show_voltage_label, NULL, 0); |
1567 | static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1); | 1566 | static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, show_voltage_label, NULL, 1); |
1568 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2); | 1567 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_voltage_label, NULL, 2); |
1569 | static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3); | 1568 | static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_voltage_label, NULL, 3); |
1570 | static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4); | 1569 | static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_voltage_label, NULL, 4); |
1571 | static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5); | 1570 | static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_voltage_label, NULL, 5); |
1572 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6); | 1571 | static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, show_voltage_label, NULL, 6); |
1573 | static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7); | 1572 | static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, show_voltage_label, NULL, 7); |
1574 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8); | 1573 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_voltage_label, NULL, 8); |
1575 | static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9); | 1574 | static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, show_voltage_label, NULL, 9); |
1576 | static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10); | 1575 | static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, show_voltage_label, NULL, 10); |
1577 | static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11); | 1576 | static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, show_voltage_label, NULL, 11); |
1578 | static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12); | 1577 | static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, show_voltage_label, NULL, 12); |
1579 | 1578 | ||
1580 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, | 1579 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, |
1581 | ADT7462_ALARM2 | ADT7462_V0_ALARM); | 1580 | ADT7462_ALARM2 | ADT7462_V0_ALARM); |
1582 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, | 1581 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, |
1583 | ADT7462_ALARM2 | ADT7462_V7_ALARM); | 1582 | ADT7462_ALARM2 | ADT7462_V7_ALARM); |
1584 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, | 1583 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, |
1585 | ADT7462_ALARM2 | ADT7462_V2_ALARM); | 1584 | ADT7462_ALARM2 | ADT7462_V2_ALARM); |
1586 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, | 1585 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, |
1587 | ADT7462_ALARM2 | ADT7462_V6_ALARM); | 1586 | ADT7462_ALARM2 | ADT7462_V6_ALARM); |
1588 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, | 1587 | static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, |
1589 | ADT7462_ALARM2 | ADT7462_V5_ALARM); | 1588 | ADT7462_ALARM2 | ADT7462_V5_ALARM); |
1590 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, | 1589 | static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, |
1591 | ADT7462_ALARM2 | ADT7462_V4_ALARM); | 1590 | ADT7462_ALARM2 | ADT7462_V4_ALARM); |
1592 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, | 1591 | static SENSOR_DEVICE_ATTR(in7_alarm, S_IRUGO, show_alarm, NULL, |
1593 | ADT7462_ALARM2 | ADT7462_V3_ALARM); | 1592 | ADT7462_ALARM2 | ADT7462_V3_ALARM); |
1594 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, | 1593 | static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, |
1595 | ADT7462_ALARM2 | ADT7462_V1_ALARM); | 1594 | ADT7462_ALARM2 | ADT7462_V1_ALARM); |
1596 | static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, | 1595 | static SENSOR_DEVICE_ATTR(in9_alarm, S_IRUGO, show_alarm, NULL, |
1597 | ADT7462_ALARM3 | ADT7462_V10_ALARM); | 1596 | ADT7462_ALARM3 | ADT7462_V10_ALARM); |
1598 | static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, | 1597 | static SENSOR_DEVICE_ATTR(in10_alarm, S_IRUGO, show_alarm, NULL, |
1599 | ADT7462_ALARM3 | ADT7462_V9_ALARM); | 1598 | ADT7462_ALARM3 | ADT7462_V9_ALARM); |
1600 | static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, | 1599 | static SENSOR_DEVICE_ATTR(in11_alarm, S_IRUGO, show_alarm, NULL, |
1601 | ADT7462_ALARM3 | ADT7462_V8_ALARM); | 1600 | ADT7462_ALARM3 | ADT7462_V8_ALARM); |
1602 | static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, | 1601 | static SENSOR_DEVICE_ATTR(in12_alarm, S_IRUGO, show_alarm, NULL, |
1603 | ADT7462_ALARM3 | ADT7462_V11_ALARM); | 1602 | ADT7462_ALARM3 | ADT7462_V11_ALARM); |
1604 | static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, | 1603 | static SENSOR_DEVICE_ATTR(in13_alarm, S_IRUGO, show_alarm, NULL, |
1605 | ADT7462_ALARM3 | ADT7462_V12_ALARM); | 1604 | ADT7462_ALARM3 | ADT7462_V12_ALARM); |
1606 | 1605 | ||
1607 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, | 1606 | static SENSOR_DEVICE_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, |
1608 | set_fan_min, 0); | 1607 | set_fan_min, 0); |
1609 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, | 1608 | static SENSOR_DEVICE_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, |
1610 | set_fan_min, 1); | 1609 | set_fan_min, 1); |
1611 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, | 1610 | static SENSOR_DEVICE_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, |
1612 | set_fan_min, 2); | 1611 | set_fan_min, 2); |
1613 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, | 1612 | static SENSOR_DEVICE_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, |
1614 | set_fan_min, 3); | 1613 | set_fan_min, 3); |
1615 | static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, | 1614 | static SENSOR_DEVICE_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, |
1616 | set_fan_min, 4); | 1615 | set_fan_min, 4); |
1617 | static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, | 1616 | static SENSOR_DEVICE_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, |
1618 | set_fan_min, 5); | 1617 | set_fan_min, 5); |
1619 | static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, | 1618 | static SENSOR_DEVICE_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, |
1620 | set_fan_min, 6); | 1619 | set_fan_min, 6); |
1621 | static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min, | 1620 | static SENSOR_DEVICE_ATTR(fan8_min, S_IWUSR | S_IRUGO, show_fan_min, |
1622 | set_fan_min, 7); | 1621 | set_fan_min, 7); |
1623 | 1622 | ||
1624 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); | 1623 | static SENSOR_DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0); |
1625 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); | 1624 | static SENSOR_DEVICE_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1); |
1626 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); | 1625 | static SENSOR_DEVICE_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2); |
1627 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); | 1626 | static SENSOR_DEVICE_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3); |
1628 | static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); | 1627 | static SENSOR_DEVICE_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4); |
1629 | static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); | 1628 | static SENSOR_DEVICE_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 5); |
1630 | static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); | 1629 | static SENSOR_DEVICE_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 6); |
1631 | static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); | 1630 | static SENSOR_DEVICE_ATTR(fan8_input, S_IRUGO, show_fan, NULL, 7); |
1632 | 1631 | ||
1633 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, | 1632 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, |
1634 | ADT7462_ALARM4 | ADT7462_F0_ALARM); | 1633 | ADT7462_ALARM4 | ADT7462_F0_ALARM); |
1635 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, | 1634 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, |
1636 | ADT7462_ALARM4 | ADT7462_F1_ALARM); | 1635 | ADT7462_ALARM4 | ADT7462_F1_ALARM); |
1637 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, | 1636 | static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, |
1638 | ADT7462_ALARM4 | ADT7462_F2_ALARM); | 1637 | ADT7462_ALARM4 | ADT7462_F2_ALARM); |
1639 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, | 1638 | static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, |
1640 | ADT7462_ALARM4 | ADT7462_F3_ALARM); | 1639 | ADT7462_ALARM4 | ADT7462_F3_ALARM); |
1641 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, | 1640 | static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, |
1642 | ADT7462_ALARM4 | ADT7462_F4_ALARM); | 1641 | ADT7462_ALARM4 | ADT7462_F4_ALARM); |
1643 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, | 1642 | static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, |
1644 | ADT7462_ALARM4 | ADT7462_F5_ALARM); | 1643 | ADT7462_ALARM4 | ADT7462_F5_ALARM); |
1645 | static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, | 1644 | static SENSOR_DEVICE_ATTR(fan7_alarm, S_IRUGO, show_alarm, NULL, |
1646 | ADT7462_ALARM4 | ADT7462_F6_ALARM); | 1645 | ADT7462_ALARM4 | ADT7462_F6_ALARM); |
1647 | static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_alarm, NULL, | 1646 | static SENSOR_DEVICE_ATTR(fan8_alarm, S_IRUGO, show_alarm, NULL, |
1648 | ADT7462_ALARM4 | ADT7462_F7_ALARM); | 1647 | ADT7462_ALARM4 | ADT7462_F7_ALARM); |
1649 | 1648 | ||
1650 | static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO, | 1649 | static SENSOR_DEVICE_ATTR(force_pwm_max, S_IWUSR | S_IRUGO, |
1651 | show_force_pwm_max, set_force_pwm_max, 0); | 1650 | show_force_pwm_max, set_force_pwm_max, 0); |
1652 | 1651 | ||
1653 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); | 1652 | static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0); |
1654 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); | 1653 | static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1); |
1655 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); | 1654 | static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2); |
1656 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); | 1655 | static SENSOR_DEVICE_ATTR(pwm4, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 3); |
1657 | 1656 | ||
1658 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, | 1657 | static SENSOR_DEVICE_ATTR(pwm1_auto_point1_pwm, S_IWUSR | S_IRUGO, |
1659 | show_pwm_min, set_pwm_min, 0); | 1658 | show_pwm_min, set_pwm_min, 0); |
1660 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, | 1659 | static SENSOR_DEVICE_ATTR(pwm2_auto_point1_pwm, S_IWUSR | S_IRUGO, |
1661 | show_pwm_min, set_pwm_min, 1); | 1660 | show_pwm_min, set_pwm_min, 1); |
1662 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, | 1661 | static SENSOR_DEVICE_ATTR(pwm3_auto_point1_pwm, S_IWUSR | S_IRUGO, |
1663 | show_pwm_min, set_pwm_min, 2); | 1662 | show_pwm_min, set_pwm_min, 2); |
1664 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, | 1663 | static SENSOR_DEVICE_ATTR(pwm4_auto_point1_pwm, S_IWUSR | S_IRUGO, |
1665 | show_pwm_min, set_pwm_min, 3); | 1664 | show_pwm_min, set_pwm_min, 3); |
1666 | 1665 | ||
1667 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, | 1666 | static SENSOR_DEVICE_ATTR(pwm1_auto_point2_pwm, S_IWUSR | S_IRUGO, |
1668 | show_pwm_max, set_pwm_max, 0); | 1667 | show_pwm_max, set_pwm_max, 0); |
1669 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, | 1668 | static SENSOR_DEVICE_ATTR(pwm2_auto_point2_pwm, S_IWUSR | S_IRUGO, |
1670 | show_pwm_max, set_pwm_max, 1); | 1669 | show_pwm_max, set_pwm_max, 1); |
1671 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, | 1670 | static SENSOR_DEVICE_ATTR(pwm3_auto_point2_pwm, S_IWUSR | S_IRUGO, |
1672 | show_pwm_max, set_pwm_max, 2); | 1671 | show_pwm_max, set_pwm_max, 2); |
1673 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, | 1672 | static SENSOR_DEVICE_ATTR(pwm4_auto_point2_pwm, S_IWUSR | S_IRUGO, |
1674 | show_pwm_max, set_pwm_max, 3); | 1673 | show_pwm_max, set_pwm_max, 3); |
1675 | 1674 | ||
1676 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_hyst, S_IWUSR | S_IRUGO, | 1675 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_hyst, S_IWUSR | S_IRUGO, |
1677 | show_pwm_hyst, set_pwm_hyst, 0); | 1676 | show_pwm_hyst, set_pwm_hyst, 0); |
1678 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_hyst, S_IWUSR | S_IRUGO, | 1677 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_hyst, S_IWUSR | S_IRUGO, |
1679 | show_pwm_hyst, set_pwm_hyst, 1); | 1678 | show_pwm_hyst, set_pwm_hyst, 1); |
1680 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_hyst, S_IWUSR | S_IRUGO, | 1679 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_hyst, S_IWUSR | S_IRUGO, |
1681 | show_pwm_hyst, set_pwm_hyst, 2); | 1680 | show_pwm_hyst, set_pwm_hyst, 2); |
1682 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_hyst, S_IWUSR | S_IRUGO, | 1681 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_hyst, S_IWUSR | S_IRUGO, |
1683 | show_pwm_hyst, set_pwm_hyst, 3); | 1682 | show_pwm_hyst, set_pwm_hyst, 3); |
1684 | 1683 | ||
1685 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_hyst, S_IWUSR | S_IRUGO, | 1684 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_hyst, S_IWUSR | S_IRUGO, |
1686 | show_pwm_hyst, set_pwm_hyst, 0); | 1685 | show_pwm_hyst, set_pwm_hyst, 0); |
1687 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_hyst, S_IWUSR | S_IRUGO, | 1686 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_hyst, S_IWUSR | S_IRUGO, |
1688 | show_pwm_hyst, set_pwm_hyst, 1); | 1687 | show_pwm_hyst, set_pwm_hyst, 1); |
1689 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_hyst, S_IWUSR | S_IRUGO, | 1688 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_hyst, S_IWUSR | S_IRUGO, |
1690 | show_pwm_hyst, set_pwm_hyst, 2); | 1689 | show_pwm_hyst, set_pwm_hyst, 2); |
1691 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_hyst, S_IWUSR | S_IRUGO, | 1690 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_hyst, S_IWUSR | S_IRUGO, |
1692 | show_pwm_hyst, set_pwm_hyst, 3); | 1691 | show_pwm_hyst, set_pwm_hyst, 3); |
1693 | 1692 | ||
1694 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO, | 1693 | static SENSOR_DEVICE_ATTR(temp1_auto_point1_temp, S_IWUSR | S_IRUGO, |
1695 | show_pwm_tmin, set_pwm_tmin, 0); | 1694 | show_pwm_tmin, set_pwm_tmin, 0); |
1696 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, | 1695 | static SENSOR_DEVICE_ATTR(temp2_auto_point1_temp, S_IWUSR | S_IRUGO, |
1697 | show_pwm_tmin, set_pwm_tmin, 1); | 1696 | show_pwm_tmin, set_pwm_tmin, 1); |
1698 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO, | 1697 | static SENSOR_DEVICE_ATTR(temp3_auto_point1_temp, S_IWUSR | S_IRUGO, |
1699 | show_pwm_tmin, set_pwm_tmin, 2); | 1698 | show_pwm_tmin, set_pwm_tmin, 2); |
1700 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_temp, S_IWUSR | S_IRUGO, | 1699 | static SENSOR_DEVICE_ATTR(temp4_auto_point1_temp, S_IWUSR | S_IRUGO, |
1701 | show_pwm_tmin, set_pwm_tmin, 3); | 1700 | show_pwm_tmin, set_pwm_tmin, 3); |
1702 | 1701 | ||
1703 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, | 1702 | static SENSOR_DEVICE_ATTR(temp1_auto_point2_temp, S_IWUSR | S_IRUGO, |
1704 | show_pwm_tmax, set_pwm_tmax, 0); | 1703 | show_pwm_tmax, set_pwm_tmax, 0); |
1705 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, | 1704 | static SENSOR_DEVICE_ATTR(temp2_auto_point2_temp, S_IWUSR | S_IRUGO, |
1706 | show_pwm_tmax, set_pwm_tmax, 1); | 1705 | show_pwm_tmax, set_pwm_tmax, 1); |
1707 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO, | 1706 | static SENSOR_DEVICE_ATTR(temp3_auto_point2_temp, S_IWUSR | S_IRUGO, |
1708 | show_pwm_tmax, set_pwm_tmax, 2); | 1707 | show_pwm_tmax, set_pwm_tmax, 2); |
1709 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_temp, S_IWUSR | S_IRUGO, | 1708 | static SENSOR_DEVICE_ATTR(temp4_auto_point2_temp, S_IWUSR | S_IRUGO, |
1710 | show_pwm_tmax, set_pwm_tmax, 3); | 1709 | show_pwm_tmax, set_pwm_tmax, 3); |
1711 | 1710 | ||
1712 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | 1711 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IWUSR | S_IRUGO, show_pwm_auto, |
1713 | set_pwm_auto, 0); | 1712 | set_pwm_auto, 0); |
1714 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | 1713 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IWUSR | S_IRUGO, show_pwm_auto, |
1715 | set_pwm_auto, 1); | 1714 | set_pwm_auto, 1); |
1716 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | 1715 | static SENSOR_DEVICE_ATTR(pwm3_enable, S_IWUSR | S_IRUGO, show_pwm_auto, |
1717 | set_pwm_auto, 2); | 1716 | set_pwm_auto, 2); |
1718 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, | 1717 | static SENSOR_DEVICE_ATTR(pwm4_enable, S_IWUSR | S_IRUGO, show_pwm_auto, |
1719 | set_pwm_auto, 3); | 1718 | set_pwm_auto, 3); |
1720 | 1719 | ||
1721 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, | 1720 | static SENSOR_DEVICE_ATTR(pwm1_auto_channels_temp, S_IWUSR | S_IRUGO, |
1722 | show_pwm_auto_temp, set_pwm_auto_temp, 0); | 1721 | show_pwm_auto_temp, set_pwm_auto_temp, 0); |
1723 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, | 1722 | static SENSOR_DEVICE_ATTR(pwm2_auto_channels_temp, S_IWUSR | S_IRUGO, |
1724 | show_pwm_auto_temp, set_pwm_auto_temp, 1); | 1723 | show_pwm_auto_temp, set_pwm_auto_temp, 1); |
1725 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, | 1724 | static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO, |
1726 | show_pwm_auto_temp, set_pwm_auto_temp, 2); | 1725 | show_pwm_auto_temp, set_pwm_auto_temp, 2); |
1727 | static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, | 1726 | static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO, |
1728 | show_pwm_auto_temp, set_pwm_auto_temp, 3); | 1727 | show_pwm_auto_temp, set_pwm_auto_temp, 3); |
1729 | 1728 | ||
1730 | static struct attribute *adt7462_attr[] = { | 1729 | static struct attribute *adt7462_attr[] = { |
1731 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 1730 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
1732 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 1731 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
1733 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 1732 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
1734 | &sensor_dev_attr_temp4_max.dev_attr.attr, | 1733 | &sensor_dev_attr_temp4_max.dev_attr.attr, |
1735 | 1734 | ||
1736 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 1735 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
1737 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 1736 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
1738 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 1737 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
1739 | &sensor_dev_attr_temp4_min.dev_attr.attr, | 1738 | &sensor_dev_attr_temp4_min.dev_attr.attr, |
1740 | 1739 | ||
1741 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 1740 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
1742 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 1741 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
1743 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 1742 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
1744 | &sensor_dev_attr_temp4_input.dev_attr.attr, | 1743 | &sensor_dev_attr_temp4_input.dev_attr.attr, |
1745 | 1744 | ||
1746 | &sensor_dev_attr_temp1_label.dev_attr.attr, | 1745 | &sensor_dev_attr_temp1_label.dev_attr.attr, |
1747 | &sensor_dev_attr_temp2_label.dev_attr.attr, | 1746 | &sensor_dev_attr_temp2_label.dev_attr.attr, |
1748 | &sensor_dev_attr_temp3_label.dev_attr.attr, | 1747 | &sensor_dev_attr_temp3_label.dev_attr.attr, |
1749 | &sensor_dev_attr_temp4_label.dev_attr.attr, | 1748 | &sensor_dev_attr_temp4_label.dev_attr.attr, |
1750 | 1749 | ||
1751 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | 1750 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, |
1752 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, | 1751 | &sensor_dev_attr_temp2_alarm.dev_attr.attr, |
1753 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 1752 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
1754 | &sensor_dev_attr_temp4_alarm.dev_attr.attr, | 1753 | &sensor_dev_attr_temp4_alarm.dev_attr.attr, |
1755 | 1754 | ||
1756 | &sensor_dev_attr_in1_max.dev_attr.attr, | 1755 | &sensor_dev_attr_in1_max.dev_attr.attr, |
1757 | &sensor_dev_attr_in2_max.dev_attr.attr, | 1756 | &sensor_dev_attr_in2_max.dev_attr.attr, |
1758 | &sensor_dev_attr_in3_max.dev_attr.attr, | 1757 | &sensor_dev_attr_in3_max.dev_attr.attr, |
1759 | &sensor_dev_attr_in4_max.dev_attr.attr, | 1758 | &sensor_dev_attr_in4_max.dev_attr.attr, |
1760 | &sensor_dev_attr_in5_max.dev_attr.attr, | 1759 | &sensor_dev_attr_in5_max.dev_attr.attr, |
1761 | &sensor_dev_attr_in6_max.dev_attr.attr, | 1760 | &sensor_dev_attr_in6_max.dev_attr.attr, |
1762 | &sensor_dev_attr_in7_max.dev_attr.attr, | 1761 | &sensor_dev_attr_in7_max.dev_attr.attr, |
1763 | &sensor_dev_attr_in8_max.dev_attr.attr, | 1762 | &sensor_dev_attr_in8_max.dev_attr.attr, |
1764 | &sensor_dev_attr_in9_max.dev_attr.attr, | 1763 | &sensor_dev_attr_in9_max.dev_attr.attr, |
1765 | &sensor_dev_attr_in10_max.dev_attr.attr, | 1764 | &sensor_dev_attr_in10_max.dev_attr.attr, |
1766 | &sensor_dev_attr_in11_max.dev_attr.attr, | 1765 | &sensor_dev_attr_in11_max.dev_attr.attr, |
1767 | &sensor_dev_attr_in12_max.dev_attr.attr, | 1766 | &sensor_dev_attr_in12_max.dev_attr.attr, |
1768 | &sensor_dev_attr_in13_max.dev_attr.attr, | 1767 | &sensor_dev_attr_in13_max.dev_attr.attr, |
1769 | 1768 | ||
1770 | &sensor_dev_attr_in1_min.dev_attr.attr, | 1769 | &sensor_dev_attr_in1_min.dev_attr.attr, |
1771 | &sensor_dev_attr_in2_min.dev_attr.attr, | 1770 | &sensor_dev_attr_in2_min.dev_attr.attr, |
1772 | &sensor_dev_attr_in3_min.dev_attr.attr, | 1771 | &sensor_dev_attr_in3_min.dev_attr.attr, |
1773 | &sensor_dev_attr_in4_min.dev_attr.attr, | 1772 | &sensor_dev_attr_in4_min.dev_attr.attr, |
1774 | &sensor_dev_attr_in5_min.dev_attr.attr, | 1773 | &sensor_dev_attr_in5_min.dev_attr.attr, |
1775 | &sensor_dev_attr_in6_min.dev_attr.attr, | 1774 | &sensor_dev_attr_in6_min.dev_attr.attr, |
1776 | &sensor_dev_attr_in7_min.dev_attr.attr, | 1775 | &sensor_dev_attr_in7_min.dev_attr.attr, |
1777 | &sensor_dev_attr_in8_min.dev_attr.attr, | 1776 | &sensor_dev_attr_in8_min.dev_attr.attr, |
1778 | &sensor_dev_attr_in9_min.dev_attr.attr, | 1777 | &sensor_dev_attr_in9_min.dev_attr.attr, |
1779 | &sensor_dev_attr_in10_min.dev_attr.attr, | 1778 | &sensor_dev_attr_in10_min.dev_attr.attr, |
1780 | &sensor_dev_attr_in11_min.dev_attr.attr, | 1779 | &sensor_dev_attr_in11_min.dev_attr.attr, |
1781 | &sensor_dev_attr_in12_min.dev_attr.attr, | 1780 | &sensor_dev_attr_in12_min.dev_attr.attr, |
1782 | &sensor_dev_attr_in13_min.dev_attr.attr, | 1781 | &sensor_dev_attr_in13_min.dev_attr.attr, |
1783 | 1782 | ||
1784 | &sensor_dev_attr_in1_input.dev_attr.attr, | 1783 | &sensor_dev_attr_in1_input.dev_attr.attr, |
1785 | &sensor_dev_attr_in2_input.dev_attr.attr, | 1784 | &sensor_dev_attr_in2_input.dev_attr.attr, |
1786 | &sensor_dev_attr_in3_input.dev_attr.attr, | 1785 | &sensor_dev_attr_in3_input.dev_attr.attr, |
1787 | &sensor_dev_attr_in4_input.dev_attr.attr, | 1786 | &sensor_dev_attr_in4_input.dev_attr.attr, |
1788 | &sensor_dev_attr_in5_input.dev_attr.attr, | 1787 | &sensor_dev_attr_in5_input.dev_attr.attr, |
1789 | &sensor_dev_attr_in6_input.dev_attr.attr, | 1788 | &sensor_dev_attr_in6_input.dev_attr.attr, |
1790 | &sensor_dev_attr_in7_input.dev_attr.attr, | 1789 | &sensor_dev_attr_in7_input.dev_attr.attr, |
1791 | &sensor_dev_attr_in8_input.dev_attr.attr, | 1790 | &sensor_dev_attr_in8_input.dev_attr.attr, |
1792 | &sensor_dev_attr_in9_input.dev_attr.attr, | 1791 | &sensor_dev_attr_in9_input.dev_attr.attr, |
1793 | &sensor_dev_attr_in10_input.dev_attr.attr, | 1792 | &sensor_dev_attr_in10_input.dev_attr.attr, |
1794 | &sensor_dev_attr_in11_input.dev_attr.attr, | 1793 | &sensor_dev_attr_in11_input.dev_attr.attr, |
1795 | &sensor_dev_attr_in12_input.dev_attr.attr, | 1794 | &sensor_dev_attr_in12_input.dev_attr.attr, |
1796 | &sensor_dev_attr_in13_input.dev_attr.attr, | 1795 | &sensor_dev_attr_in13_input.dev_attr.attr, |
1797 | 1796 | ||
1798 | &sensor_dev_attr_in1_label.dev_attr.attr, | 1797 | &sensor_dev_attr_in1_label.dev_attr.attr, |
1799 | &sensor_dev_attr_in2_label.dev_attr.attr, | 1798 | &sensor_dev_attr_in2_label.dev_attr.attr, |
1800 | &sensor_dev_attr_in3_label.dev_attr.attr, | 1799 | &sensor_dev_attr_in3_label.dev_attr.attr, |
1801 | &sensor_dev_attr_in4_label.dev_attr.attr, | 1800 | &sensor_dev_attr_in4_label.dev_attr.attr, |
1802 | &sensor_dev_attr_in5_label.dev_attr.attr, | 1801 | &sensor_dev_attr_in5_label.dev_attr.attr, |
1803 | &sensor_dev_attr_in6_label.dev_attr.attr, | 1802 | &sensor_dev_attr_in6_label.dev_attr.attr, |
1804 | &sensor_dev_attr_in7_label.dev_attr.attr, | 1803 | &sensor_dev_attr_in7_label.dev_attr.attr, |
1805 | &sensor_dev_attr_in8_label.dev_attr.attr, | 1804 | &sensor_dev_attr_in8_label.dev_attr.attr, |
1806 | &sensor_dev_attr_in9_label.dev_attr.attr, | 1805 | &sensor_dev_attr_in9_label.dev_attr.attr, |
1807 | &sensor_dev_attr_in10_label.dev_attr.attr, | 1806 | &sensor_dev_attr_in10_label.dev_attr.attr, |
1808 | &sensor_dev_attr_in11_label.dev_attr.attr, | 1807 | &sensor_dev_attr_in11_label.dev_attr.attr, |
1809 | &sensor_dev_attr_in12_label.dev_attr.attr, | 1808 | &sensor_dev_attr_in12_label.dev_attr.attr, |
1810 | &sensor_dev_attr_in13_label.dev_attr.attr, | 1809 | &sensor_dev_attr_in13_label.dev_attr.attr, |
1811 | 1810 | ||
1812 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | 1811 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
1813 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | 1812 | &sensor_dev_attr_in2_alarm.dev_attr.attr, |
1814 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | 1813 | &sensor_dev_attr_in3_alarm.dev_attr.attr, |
1815 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | 1814 | &sensor_dev_attr_in4_alarm.dev_attr.attr, |
1816 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | 1815 | &sensor_dev_attr_in5_alarm.dev_attr.attr, |
1817 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | 1816 | &sensor_dev_attr_in6_alarm.dev_attr.attr, |
1818 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | 1817 | &sensor_dev_attr_in7_alarm.dev_attr.attr, |
1819 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | 1818 | &sensor_dev_attr_in8_alarm.dev_attr.attr, |
1820 | &sensor_dev_attr_in9_alarm.dev_attr.attr, | 1819 | &sensor_dev_attr_in9_alarm.dev_attr.attr, |
1821 | &sensor_dev_attr_in10_alarm.dev_attr.attr, | 1820 | &sensor_dev_attr_in10_alarm.dev_attr.attr, |
1822 | &sensor_dev_attr_in11_alarm.dev_attr.attr, | 1821 | &sensor_dev_attr_in11_alarm.dev_attr.attr, |
1823 | &sensor_dev_attr_in12_alarm.dev_attr.attr, | 1822 | &sensor_dev_attr_in12_alarm.dev_attr.attr, |
1824 | &sensor_dev_attr_in13_alarm.dev_attr.attr, | 1823 | &sensor_dev_attr_in13_alarm.dev_attr.attr, |
1825 | 1824 | ||
1826 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 1825 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
1827 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 1826 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
1828 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 1827 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
1829 | &sensor_dev_attr_fan4_min.dev_attr.attr, | 1828 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
1830 | &sensor_dev_attr_fan5_min.dev_attr.attr, | 1829 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
1831 | &sensor_dev_attr_fan6_min.dev_attr.attr, | 1830 | &sensor_dev_attr_fan6_min.dev_attr.attr, |
1832 | &sensor_dev_attr_fan7_min.dev_attr.attr, | 1831 | &sensor_dev_attr_fan7_min.dev_attr.attr, |
1833 | &sensor_dev_attr_fan8_min.dev_attr.attr, | 1832 | &sensor_dev_attr_fan8_min.dev_attr.attr, |
1834 | 1833 | ||
1835 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 1834 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
1836 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 1835 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
1837 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 1836 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
1838 | &sensor_dev_attr_fan4_input.dev_attr.attr, | 1837 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
1839 | &sensor_dev_attr_fan5_input.dev_attr.attr, | 1838 | &sensor_dev_attr_fan5_input.dev_attr.attr, |
1840 | &sensor_dev_attr_fan6_input.dev_attr.attr, | 1839 | &sensor_dev_attr_fan6_input.dev_attr.attr, |
1841 | &sensor_dev_attr_fan7_input.dev_attr.attr, | 1840 | &sensor_dev_attr_fan7_input.dev_attr.attr, |
1842 | &sensor_dev_attr_fan8_input.dev_attr.attr, | 1841 | &sensor_dev_attr_fan8_input.dev_attr.attr, |
1843 | 1842 | ||
1844 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | 1843 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, |
1845 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | 1844 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, |
1846 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, | 1845 | &sensor_dev_attr_fan3_alarm.dev_attr.attr, |
1847 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, | 1846 | &sensor_dev_attr_fan4_alarm.dev_attr.attr, |
1848 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, | 1847 | &sensor_dev_attr_fan5_alarm.dev_attr.attr, |
1849 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, | 1848 | &sensor_dev_attr_fan6_alarm.dev_attr.attr, |
1850 | &sensor_dev_attr_fan7_alarm.dev_attr.attr, | 1849 | &sensor_dev_attr_fan7_alarm.dev_attr.attr, |
1851 | &sensor_dev_attr_fan8_alarm.dev_attr.attr, | 1850 | &sensor_dev_attr_fan8_alarm.dev_attr.attr, |
1852 | 1851 | ||
1853 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, | 1852 | &sensor_dev_attr_force_pwm_max.dev_attr.attr, |
1854 | &sensor_dev_attr_pwm1.dev_attr.attr, | 1853 | &sensor_dev_attr_pwm1.dev_attr.attr, |
1855 | &sensor_dev_attr_pwm2.dev_attr.attr, | 1854 | &sensor_dev_attr_pwm2.dev_attr.attr, |
1856 | &sensor_dev_attr_pwm3.dev_attr.attr, | 1855 | &sensor_dev_attr_pwm3.dev_attr.attr, |
1857 | &sensor_dev_attr_pwm4.dev_attr.attr, | 1856 | &sensor_dev_attr_pwm4.dev_attr.attr, |
1858 | 1857 | ||
1859 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, | 1858 | &sensor_dev_attr_pwm1_auto_point1_pwm.dev_attr.attr, |
1860 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, | 1859 | &sensor_dev_attr_pwm2_auto_point1_pwm.dev_attr.attr, |
1861 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, | 1860 | &sensor_dev_attr_pwm3_auto_point1_pwm.dev_attr.attr, |
1862 | &sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr, | 1861 | &sensor_dev_attr_pwm4_auto_point1_pwm.dev_attr.attr, |
1863 | 1862 | ||
1864 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, | 1863 | &sensor_dev_attr_pwm1_auto_point2_pwm.dev_attr.attr, |
1865 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, | 1864 | &sensor_dev_attr_pwm2_auto_point2_pwm.dev_attr.attr, |
1866 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, | 1865 | &sensor_dev_attr_pwm3_auto_point2_pwm.dev_attr.attr, |
1867 | &sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr, | 1866 | &sensor_dev_attr_pwm4_auto_point2_pwm.dev_attr.attr, |
1868 | 1867 | ||
1869 | &sensor_dev_attr_temp1_auto_point1_hyst.dev_attr.attr, | 1868 | &sensor_dev_attr_temp1_auto_point1_hyst.dev_attr.attr, |
1870 | &sensor_dev_attr_temp2_auto_point1_hyst.dev_attr.attr, | 1869 | &sensor_dev_attr_temp2_auto_point1_hyst.dev_attr.attr, |
1871 | &sensor_dev_attr_temp3_auto_point1_hyst.dev_attr.attr, | 1870 | &sensor_dev_attr_temp3_auto_point1_hyst.dev_attr.attr, |
1872 | &sensor_dev_attr_temp4_auto_point1_hyst.dev_attr.attr, | 1871 | &sensor_dev_attr_temp4_auto_point1_hyst.dev_attr.attr, |
1873 | 1872 | ||
1874 | &sensor_dev_attr_temp1_auto_point2_hyst.dev_attr.attr, | 1873 | &sensor_dev_attr_temp1_auto_point2_hyst.dev_attr.attr, |
1875 | &sensor_dev_attr_temp2_auto_point2_hyst.dev_attr.attr, | 1874 | &sensor_dev_attr_temp2_auto_point2_hyst.dev_attr.attr, |
1876 | &sensor_dev_attr_temp3_auto_point2_hyst.dev_attr.attr, | 1875 | &sensor_dev_attr_temp3_auto_point2_hyst.dev_attr.attr, |
1877 | &sensor_dev_attr_temp4_auto_point2_hyst.dev_attr.attr, | 1876 | &sensor_dev_attr_temp4_auto_point2_hyst.dev_attr.attr, |
1878 | 1877 | ||
1879 | &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, | 1878 | &sensor_dev_attr_temp1_auto_point1_temp.dev_attr.attr, |
1880 | &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, | 1879 | &sensor_dev_attr_temp2_auto_point1_temp.dev_attr.attr, |
1881 | &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, | 1880 | &sensor_dev_attr_temp3_auto_point1_temp.dev_attr.attr, |
1882 | &sensor_dev_attr_temp4_auto_point1_temp.dev_attr.attr, | 1881 | &sensor_dev_attr_temp4_auto_point1_temp.dev_attr.attr, |
1883 | 1882 | ||
1884 | &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, | 1883 | &sensor_dev_attr_temp1_auto_point2_temp.dev_attr.attr, |
1885 | &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, | 1884 | &sensor_dev_attr_temp2_auto_point2_temp.dev_attr.attr, |
1886 | &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, | 1885 | &sensor_dev_attr_temp3_auto_point2_temp.dev_attr.attr, |
1887 | &sensor_dev_attr_temp4_auto_point2_temp.dev_attr.attr, | 1886 | &sensor_dev_attr_temp4_auto_point2_temp.dev_attr.attr, |
1888 | 1887 | ||
1889 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, | 1888 | &sensor_dev_attr_pwm1_enable.dev_attr.attr, |
1890 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, | 1889 | &sensor_dev_attr_pwm2_enable.dev_attr.attr, |
1891 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, | 1890 | &sensor_dev_attr_pwm3_enable.dev_attr.attr, |
1892 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, | 1891 | &sensor_dev_attr_pwm4_enable.dev_attr.attr, |
1893 | 1892 | ||
1894 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, | 1893 | &sensor_dev_attr_pwm1_auto_channels_temp.dev_attr.attr, |
1895 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, | 1894 | &sensor_dev_attr_pwm2_auto_channels_temp.dev_attr.attr, |
1896 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, | 1895 | &sensor_dev_attr_pwm3_auto_channels_temp.dev_attr.attr, |
1897 | &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, | 1896 | &sensor_dev_attr_pwm4_auto_channels_temp.dev_attr.attr, |
1898 | NULL | 1897 | NULL |
1899 | }; | 1898 | }; |
1900 | 1899 | ||
1901 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 1900 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1902 | static int adt7462_detect(struct i2c_client *client, | 1901 | static int adt7462_detect(struct i2c_client *client, |
1903 | struct i2c_board_info *info) | 1902 | struct i2c_board_info *info) |
1904 | { | 1903 | { |
1905 | struct i2c_adapter *adapter = client->adapter; | 1904 | struct i2c_adapter *adapter = client->adapter; |
1906 | int vendor, device, revision; | 1905 | int vendor, device, revision; |
1907 | 1906 | ||
1908 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1907 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1909 | return -ENODEV; | 1908 | return -ENODEV; |
1910 | 1909 | ||
1911 | vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR); | 1910 | vendor = i2c_smbus_read_byte_data(client, ADT7462_REG_VENDOR); |
1912 | if (vendor != ADT7462_VENDOR) | 1911 | if (vendor != ADT7462_VENDOR) |
1913 | return -ENODEV; | 1912 | return -ENODEV; |
1914 | 1913 | ||
1915 | device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE); | 1914 | device = i2c_smbus_read_byte_data(client, ADT7462_REG_DEVICE); |
1916 | if (device != ADT7462_DEVICE) | 1915 | if (device != ADT7462_DEVICE) |
1917 | return -ENODEV; | 1916 | return -ENODEV; |
1918 | 1917 | ||
1919 | revision = i2c_smbus_read_byte_data(client, ADT7462_REG_REVISION); | 1918 | revision = i2c_smbus_read_byte_data(client, ADT7462_REG_REVISION); |
1920 | if (revision != ADT7462_REVISION) | 1919 | if (revision != ADT7462_REVISION) |
1921 | return -ENODEV; | 1920 | return -ENODEV; |
1922 | 1921 | ||
1923 | strlcpy(info->type, "adt7462", I2C_NAME_SIZE); | 1922 | strlcpy(info->type, "adt7462", I2C_NAME_SIZE); |
1924 | 1923 | ||
1925 | return 0; | 1924 | return 0; |
1926 | } | 1925 | } |
1927 | 1926 | ||
1928 | static int adt7462_probe(struct i2c_client *client, | 1927 | static int adt7462_probe(struct i2c_client *client, |
1929 | const struct i2c_device_id *id) | 1928 | const struct i2c_device_id *id) |
1930 | { | 1929 | { |
1931 | struct adt7462_data *data; | 1930 | struct adt7462_data *data; |
1932 | int err; | 1931 | int err; |
1933 | 1932 | ||
1934 | data = devm_kzalloc(&client->dev, sizeof(struct adt7462_data), | 1933 | data = devm_kzalloc(&client->dev, sizeof(struct adt7462_data), |
1935 | GFP_KERNEL); | 1934 | GFP_KERNEL); |
1936 | if (!data) | 1935 | if (!data) |
1937 | return -ENOMEM; | 1936 | return -ENOMEM; |
1938 | 1937 | ||
1939 | i2c_set_clientdata(client, data); | 1938 | i2c_set_clientdata(client, data); |
1940 | mutex_init(&data->lock); | 1939 | mutex_init(&data->lock); |
1941 | 1940 | ||
1942 | dev_info(&client->dev, "%s chip found\n", client->name); | 1941 | dev_info(&client->dev, "%s chip found\n", client->name); |
1943 | 1942 | ||
1944 | /* Register sysfs hooks */ | 1943 | /* Register sysfs hooks */ |
1945 | data->attrs.attrs = adt7462_attr; | 1944 | data->attrs.attrs = adt7462_attr; |
1946 | err = sysfs_create_group(&client->dev.kobj, &data->attrs); | 1945 | err = sysfs_create_group(&client->dev.kobj, &data->attrs); |
1947 | if (err) | 1946 | if (err) |
1948 | return err; | 1947 | return err; |
1949 | 1948 | ||
1950 | data->hwmon_dev = hwmon_device_register(&client->dev); | 1949 | data->hwmon_dev = hwmon_device_register(&client->dev); |
1951 | if (IS_ERR(data->hwmon_dev)) { | 1950 | if (IS_ERR(data->hwmon_dev)) { |
1952 | err = PTR_ERR(data->hwmon_dev); | 1951 | err = PTR_ERR(data->hwmon_dev); |
1953 | goto exit_remove; | 1952 | goto exit_remove; |
1954 | } | 1953 | } |
1955 | 1954 | ||
1956 | return 0; | 1955 | return 0; |
1957 | 1956 | ||
1958 | exit_remove: | 1957 | exit_remove: |
1959 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 1958 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
1960 | return err; | 1959 | return err; |
1961 | } | 1960 | } |
1962 | 1961 | ||
1963 | static int adt7462_remove(struct i2c_client *client) | 1962 | static int adt7462_remove(struct i2c_client *client) |
1964 | { | 1963 | { |
1965 | struct adt7462_data *data = i2c_get_clientdata(client); | 1964 | struct adt7462_data *data = i2c_get_clientdata(client); |
1966 | 1965 | ||
1967 | hwmon_device_unregister(data->hwmon_dev); | 1966 | hwmon_device_unregister(data->hwmon_dev); |
1968 | sysfs_remove_group(&client->dev.kobj, &data->attrs); | 1967 | sysfs_remove_group(&client->dev.kobj, &data->attrs); |
1969 | return 0; | 1968 | return 0; |
1970 | } | 1969 | } |
1971 | 1970 | ||
1972 | module_i2c_driver(adt7462_driver); | 1971 | module_i2c_driver(adt7462_driver); |
1973 | 1972 | ||
1974 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | 1973 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); |
1975 | MODULE_DESCRIPTION("ADT7462 driver"); | 1974 | MODULE_DESCRIPTION("ADT7462 driver"); |
1976 | MODULE_LICENSE("GPL"); | 1975 | MODULE_LICENSE("GPL"); |
1977 | 1976 |
drivers/hwmon/da9052-hwmon.c
1 | /* | 1 | /* |
2 | * HWMON Driver for Dialog DA9052 | 2 | * HWMON Driver for Dialog DA9052 |
3 | * | 3 | * |
4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. | 4 | * Copyright(c) 2012 Dialog Semiconductor Ltd. |
5 | * | 5 | * |
6 | * Author: David Dajun Chen <dchen@diasemi.com> | 6 | * Author: David Dajun Chen <dchen@diasemi.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify it | 8 | * This program is free software; you can redistribute it and/or modify it |
9 | * under the terms of the GNU General Public License as published by the | 9 | * under the terms of the GNU General Public License as published by the |
10 | * Free Software Foundation; either version 2 of the License, or (at your | 10 | * Free Software Foundation; either version 2 of the License, or (at your |
11 | * option) any later version. | 11 | * option) any later version. |
12 | * | 12 | * |
13 | */ | 13 | */ |
14 | 14 | ||
15 | #include <linux/delay.h> | ||
16 | #include <linux/err.h> | 15 | #include <linux/err.h> |
17 | #include <linux/hwmon.h> | 16 | #include <linux/hwmon.h> |
18 | #include <linux/hwmon-sysfs.h> | 17 | #include <linux/hwmon-sysfs.h> |
19 | #include <linux/init.h> | 18 | #include <linux/init.h> |
20 | #include <linux/kernel.h> | 19 | #include <linux/kernel.h> |
21 | #include <linux/module.h> | 20 | #include <linux/module.h> |
22 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
23 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
24 | 23 | ||
25 | #include <linux/mfd/da9052/da9052.h> | 24 | #include <linux/mfd/da9052/da9052.h> |
26 | #include <linux/mfd/da9052/reg.h> | 25 | #include <linux/mfd/da9052/reg.h> |
27 | 26 | ||
28 | struct da9052_hwmon { | 27 | struct da9052_hwmon { |
29 | struct da9052 *da9052; | 28 | struct da9052 *da9052; |
30 | struct device *class_device; | 29 | struct device *class_device; |
31 | struct mutex hwmon_lock; | 30 | struct mutex hwmon_lock; |
32 | }; | 31 | }; |
33 | 32 | ||
34 | static const char * const input_names[] = { | 33 | static const char * const input_names[] = { |
35 | [DA9052_ADC_VDDOUT] = "VDDOUT", | 34 | [DA9052_ADC_VDDOUT] = "VDDOUT", |
36 | [DA9052_ADC_ICH] = "CHARGING CURRENT", | 35 | [DA9052_ADC_ICH] = "CHARGING CURRENT", |
37 | [DA9052_ADC_TBAT] = "BATTERY TEMP", | 36 | [DA9052_ADC_TBAT] = "BATTERY TEMP", |
38 | [DA9052_ADC_VBAT] = "BATTERY VOLTAGE", | 37 | [DA9052_ADC_VBAT] = "BATTERY VOLTAGE", |
39 | [DA9052_ADC_IN4] = "ADC IN4", | 38 | [DA9052_ADC_IN4] = "ADC IN4", |
40 | [DA9052_ADC_IN5] = "ADC IN5", | 39 | [DA9052_ADC_IN5] = "ADC IN5", |
41 | [DA9052_ADC_IN6] = "ADC IN6", | 40 | [DA9052_ADC_IN6] = "ADC IN6", |
42 | [DA9052_ADC_TJUNC] = "BATTERY JUNCTION TEMP", | 41 | [DA9052_ADC_TJUNC] = "BATTERY JUNCTION TEMP", |
43 | [DA9052_ADC_VBBAT] = "BACK-UP BATTERY VOLTAGE", | 42 | [DA9052_ADC_VBBAT] = "BACK-UP BATTERY VOLTAGE", |
44 | }; | 43 | }; |
45 | 44 | ||
46 | /* Conversion function for VDDOUT and VBAT */ | 45 | /* Conversion function for VDDOUT and VBAT */ |
47 | static inline int volt_reg_to_mV(int value) | 46 | static inline int volt_reg_to_mV(int value) |
48 | { | 47 | { |
49 | return DIV_ROUND_CLOSEST(value * 1000, 512) + 2500; | 48 | return DIV_ROUND_CLOSEST(value * 1000, 512) + 2500; |
50 | } | 49 | } |
51 | 50 | ||
52 | /* Conversion function for ADC channels 4, 5 and 6 */ | 51 | /* Conversion function for ADC channels 4, 5 and 6 */ |
53 | static inline int input_reg_to_mV(int value) | 52 | static inline int input_reg_to_mV(int value) |
54 | { | 53 | { |
55 | return DIV_ROUND_CLOSEST(value * 2500, 1023); | 54 | return DIV_ROUND_CLOSEST(value * 2500, 1023); |
56 | } | 55 | } |
57 | 56 | ||
58 | /* Conversion function for VBBAT */ | 57 | /* Conversion function for VBBAT */ |
59 | static inline int vbbat_reg_to_mV(int value) | 58 | static inline int vbbat_reg_to_mV(int value) |
60 | { | 59 | { |
61 | return DIV_ROUND_CLOSEST(value * 2500, 512); | 60 | return DIV_ROUND_CLOSEST(value * 2500, 512); |
62 | } | 61 | } |
63 | 62 | ||
64 | static int da9052_enable_vddout_channel(struct da9052 *da9052) | 63 | static int da9052_enable_vddout_channel(struct da9052 *da9052) |
65 | { | 64 | { |
66 | int ret; | 65 | int ret; |
67 | 66 | ||
68 | ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); | 67 | ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); |
69 | if (ret < 0) | 68 | if (ret < 0) |
70 | return ret; | 69 | return ret; |
71 | 70 | ||
72 | ret |= DA9052_ADCCONT_AUTOVDDEN; | 71 | ret |= DA9052_ADCCONT_AUTOVDDEN; |
73 | 72 | ||
74 | return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); | 73 | return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); |
75 | } | 74 | } |
76 | 75 | ||
77 | static int da9052_disable_vddout_channel(struct da9052 *da9052) | 76 | static int da9052_disable_vddout_channel(struct da9052 *da9052) |
78 | { | 77 | { |
79 | int ret; | 78 | int ret; |
80 | 79 | ||
81 | ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); | 80 | ret = da9052_reg_read(da9052, DA9052_ADC_CONT_REG); |
82 | if (ret < 0) | 81 | if (ret < 0) |
83 | return ret; | 82 | return ret; |
84 | 83 | ||
85 | ret &= ~DA9052_ADCCONT_AUTOVDDEN; | 84 | ret &= ~DA9052_ADCCONT_AUTOVDDEN; |
86 | 85 | ||
87 | return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); | 86 | return da9052_reg_write(da9052, DA9052_ADC_CONT_REG, ret); |
88 | } | 87 | } |
89 | 88 | ||
90 | static ssize_t da9052_read_vddout(struct device *dev, | 89 | static ssize_t da9052_read_vddout(struct device *dev, |
91 | struct device_attribute *devattr, char *buf) | 90 | struct device_attribute *devattr, char *buf) |
92 | { | 91 | { |
93 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); | 92 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); |
94 | int ret, vdd; | 93 | int ret, vdd; |
95 | 94 | ||
96 | mutex_lock(&hwmon->hwmon_lock); | 95 | mutex_lock(&hwmon->hwmon_lock); |
97 | 96 | ||
98 | ret = da9052_enable_vddout_channel(hwmon->da9052); | 97 | ret = da9052_enable_vddout_channel(hwmon->da9052); |
99 | if (ret < 0) | 98 | if (ret < 0) |
100 | goto hwmon_err; | 99 | goto hwmon_err; |
101 | 100 | ||
102 | vdd = da9052_reg_read(hwmon->da9052, DA9052_VDD_RES_REG); | 101 | vdd = da9052_reg_read(hwmon->da9052, DA9052_VDD_RES_REG); |
103 | if (vdd < 0) { | 102 | if (vdd < 0) { |
104 | ret = vdd; | 103 | ret = vdd; |
105 | goto hwmon_err_release; | 104 | goto hwmon_err_release; |
106 | } | 105 | } |
107 | 106 | ||
108 | ret = da9052_disable_vddout_channel(hwmon->da9052); | 107 | ret = da9052_disable_vddout_channel(hwmon->da9052); |
109 | if (ret < 0) | 108 | if (ret < 0) |
110 | goto hwmon_err; | 109 | goto hwmon_err; |
111 | 110 | ||
112 | mutex_unlock(&hwmon->hwmon_lock); | 111 | mutex_unlock(&hwmon->hwmon_lock); |
113 | return sprintf(buf, "%d\n", volt_reg_to_mV(vdd)); | 112 | return sprintf(buf, "%d\n", volt_reg_to_mV(vdd)); |
114 | 113 | ||
115 | hwmon_err_release: | 114 | hwmon_err_release: |
116 | da9052_disable_vddout_channel(hwmon->da9052); | 115 | da9052_disable_vddout_channel(hwmon->da9052); |
117 | hwmon_err: | 116 | hwmon_err: |
118 | mutex_unlock(&hwmon->hwmon_lock); | 117 | mutex_unlock(&hwmon->hwmon_lock); |
119 | return ret; | 118 | return ret; |
120 | } | 119 | } |
121 | 120 | ||
122 | static ssize_t da9052_read_ich(struct device *dev, | 121 | static ssize_t da9052_read_ich(struct device *dev, |
123 | struct device_attribute *devattr, char *buf) | 122 | struct device_attribute *devattr, char *buf) |
124 | { | 123 | { |
125 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); | 124 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); |
126 | int ret; | 125 | int ret; |
127 | 126 | ||
128 | ret = da9052_reg_read(hwmon->da9052, DA9052_ICHG_AV_REG); | 127 | ret = da9052_reg_read(hwmon->da9052, DA9052_ICHG_AV_REG); |
129 | if (ret < 0) | 128 | if (ret < 0) |
130 | return ret; | 129 | return ret; |
131 | 130 | ||
132 | /* Equivalent to 3.9mA/bit in register ICHG_AV */ | 131 | /* Equivalent to 3.9mA/bit in register ICHG_AV */ |
133 | return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(ret * 39, 10)); | 132 | return sprintf(buf, "%d\n", DIV_ROUND_CLOSEST(ret * 39, 10)); |
134 | } | 133 | } |
135 | 134 | ||
136 | static ssize_t da9052_read_tbat(struct device *dev, | 135 | static ssize_t da9052_read_tbat(struct device *dev, |
137 | struct device_attribute *devattr, char *buf) | 136 | struct device_attribute *devattr, char *buf) |
138 | { | 137 | { |
139 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); | 138 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); |
140 | 139 | ||
141 | return sprintf(buf, "%d\n", da9052_adc_read_temp(hwmon->da9052)); | 140 | return sprintf(buf, "%d\n", da9052_adc_read_temp(hwmon->da9052)); |
142 | } | 141 | } |
143 | 142 | ||
144 | static ssize_t da9052_read_vbat(struct device *dev, | 143 | static ssize_t da9052_read_vbat(struct device *dev, |
145 | struct device_attribute *devattr, char *buf) | 144 | struct device_attribute *devattr, char *buf) |
146 | { | 145 | { |
147 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); | 146 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); |
148 | int ret; | 147 | int ret; |
149 | 148 | ||
150 | ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBAT); | 149 | ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBAT); |
151 | if (ret < 0) | 150 | if (ret < 0) |
152 | return ret; | 151 | return ret; |
153 | 152 | ||
154 | return sprintf(buf, "%d\n", volt_reg_to_mV(ret)); | 153 | return sprintf(buf, "%d\n", volt_reg_to_mV(ret)); |
155 | } | 154 | } |
156 | 155 | ||
157 | static ssize_t da9052_read_misc_channel(struct device *dev, | 156 | static ssize_t da9052_read_misc_channel(struct device *dev, |
158 | struct device_attribute *devattr, | 157 | struct device_attribute *devattr, |
159 | char *buf) | 158 | char *buf) |
160 | { | 159 | { |
161 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); | 160 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); |
162 | int channel = to_sensor_dev_attr(devattr)->index; | 161 | int channel = to_sensor_dev_attr(devattr)->index; |
163 | int ret; | 162 | int ret; |
164 | 163 | ||
165 | ret = da9052_adc_manual_read(hwmon->da9052, channel); | 164 | ret = da9052_adc_manual_read(hwmon->da9052, channel); |
166 | if (ret < 0) | 165 | if (ret < 0) |
167 | return ret; | 166 | return ret; |
168 | 167 | ||
169 | return sprintf(buf, "%d\n", input_reg_to_mV(ret)); | 168 | return sprintf(buf, "%d\n", input_reg_to_mV(ret)); |
170 | } | 169 | } |
171 | 170 | ||
172 | static ssize_t da9052_read_tjunc(struct device *dev, | 171 | static ssize_t da9052_read_tjunc(struct device *dev, |
173 | struct device_attribute *devattr, char *buf) | 172 | struct device_attribute *devattr, char *buf) |
174 | { | 173 | { |
175 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); | 174 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); |
176 | int tjunc; | 175 | int tjunc; |
177 | int toffset; | 176 | int toffset; |
178 | 177 | ||
179 | tjunc = da9052_reg_read(hwmon->da9052, DA9052_TJUNC_RES_REG); | 178 | tjunc = da9052_reg_read(hwmon->da9052, DA9052_TJUNC_RES_REG); |
180 | if (tjunc < 0) | 179 | if (tjunc < 0) |
181 | return tjunc; | 180 | return tjunc; |
182 | 181 | ||
183 | toffset = da9052_reg_read(hwmon->da9052, DA9052_T_OFFSET_REG); | 182 | toffset = da9052_reg_read(hwmon->da9052, DA9052_T_OFFSET_REG); |
184 | if (toffset < 0) | 183 | if (toffset < 0) |
185 | return toffset; | 184 | return toffset; |
186 | 185 | ||
187 | /* | 186 | /* |
188 | * Degrees celsius = 1.708 * (TJUNC_RES - T_OFFSET) - 108.8 | 187 | * Degrees celsius = 1.708 * (TJUNC_RES - T_OFFSET) - 108.8 |
189 | * T_OFFSET is a trim value used to improve accuracy of the result | 188 | * T_OFFSET is a trim value used to improve accuracy of the result |
190 | */ | 189 | */ |
191 | return sprintf(buf, "%d\n", 1708 * (tjunc - toffset) - 108800); | 190 | return sprintf(buf, "%d\n", 1708 * (tjunc - toffset) - 108800); |
192 | } | 191 | } |
193 | 192 | ||
194 | static ssize_t da9052_read_vbbat(struct device *dev, | 193 | static ssize_t da9052_read_vbbat(struct device *dev, |
195 | struct device_attribute *devattr, char *buf) | 194 | struct device_attribute *devattr, char *buf) |
196 | { | 195 | { |
197 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); | 196 | struct da9052_hwmon *hwmon = dev_get_drvdata(dev); |
198 | int ret; | 197 | int ret; |
199 | 198 | ||
200 | ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBBAT); | 199 | ret = da9052_adc_manual_read(hwmon->da9052, DA9052_ADC_VBBAT); |
201 | if (ret < 0) | 200 | if (ret < 0) |
202 | return ret; | 201 | return ret; |
203 | 202 | ||
204 | return sprintf(buf, "%d\n", vbbat_reg_to_mV(ret)); | 203 | return sprintf(buf, "%d\n", vbbat_reg_to_mV(ret)); |
205 | } | 204 | } |
206 | 205 | ||
207 | static ssize_t da9052_hwmon_show_name(struct device *dev, | 206 | static ssize_t da9052_hwmon_show_name(struct device *dev, |
208 | struct device_attribute *devattr, | 207 | struct device_attribute *devattr, |
209 | char *buf) | 208 | char *buf) |
210 | { | 209 | { |
211 | return sprintf(buf, "da9052-hwmon\n"); | 210 | return sprintf(buf, "da9052-hwmon\n"); |
212 | } | 211 | } |
213 | 212 | ||
214 | static ssize_t show_label(struct device *dev, | 213 | static ssize_t show_label(struct device *dev, |
215 | struct device_attribute *devattr, char *buf) | 214 | struct device_attribute *devattr, char *buf) |
216 | { | 215 | { |
217 | return sprintf(buf, "%s\n", | 216 | return sprintf(buf, "%s\n", |
218 | input_names[to_sensor_dev_attr(devattr)->index]); | 217 | input_names[to_sensor_dev_attr(devattr)->index]); |
219 | } | 218 | } |
220 | 219 | ||
221 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9052_read_vddout, NULL, | 220 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, da9052_read_vddout, NULL, |
222 | DA9052_ADC_VDDOUT); | 221 | DA9052_ADC_VDDOUT); |
223 | static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, | 222 | static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, show_label, NULL, |
224 | DA9052_ADC_VDDOUT); | 223 | DA9052_ADC_VDDOUT); |
225 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9052_read_vbat, NULL, | 224 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, da9052_read_vbat, NULL, |
226 | DA9052_ADC_VBAT); | 225 | DA9052_ADC_VBAT); |
227 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, | 226 | static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, show_label, NULL, |
228 | DA9052_ADC_VBAT); | 227 | DA9052_ADC_VBAT); |
229 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, da9052_read_misc_channel, NULL, | 228 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, da9052_read_misc_channel, NULL, |
230 | DA9052_ADC_IN4); | 229 | DA9052_ADC_IN4); |
231 | static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL, | 230 | static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, show_label, NULL, |
232 | DA9052_ADC_IN4); | 231 | DA9052_ADC_IN4); |
233 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, da9052_read_misc_channel, NULL, | 232 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, da9052_read_misc_channel, NULL, |
234 | DA9052_ADC_IN5); | 233 | DA9052_ADC_IN5); |
235 | static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL, | 234 | static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, show_label, NULL, |
236 | DA9052_ADC_IN5); | 235 | DA9052_ADC_IN5); |
237 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, da9052_read_misc_channel, NULL, | 236 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, da9052_read_misc_channel, NULL, |
238 | DA9052_ADC_IN6); | 237 | DA9052_ADC_IN6); |
239 | static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL, | 238 | static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, show_label, NULL, |
240 | DA9052_ADC_IN6); | 239 | DA9052_ADC_IN6); |
241 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, da9052_read_vbbat, NULL, | 240 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, da9052_read_vbbat, NULL, |
242 | DA9052_ADC_VBBAT); | 241 | DA9052_ADC_VBBAT); |
243 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, | 242 | static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, show_label, NULL, |
244 | DA9052_ADC_VBBAT); | 243 | DA9052_ADC_VBBAT); |
245 | 244 | ||
246 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, da9052_read_ich, NULL, | 245 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, da9052_read_ich, NULL, |
247 | DA9052_ADC_ICH); | 246 | DA9052_ADC_ICH); |
248 | static SENSOR_DEVICE_ATTR(curr1_label, S_IRUGO, show_label, NULL, | 247 | static SENSOR_DEVICE_ATTR(curr1_label, S_IRUGO, show_label, NULL, |
249 | DA9052_ADC_ICH); | 248 | DA9052_ADC_ICH); |
250 | 249 | ||
251 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, da9052_read_tbat, NULL, | 250 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, da9052_read_tbat, NULL, |
252 | DA9052_ADC_TBAT); | 251 | DA9052_ADC_TBAT); |
253 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, | 252 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL, |
254 | DA9052_ADC_TBAT); | 253 | DA9052_ADC_TBAT); |
255 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, da9052_read_tjunc, NULL, | 254 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, da9052_read_tjunc, NULL, |
256 | DA9052_ADC_TJUNC); | 255 | DA9052_ADC_TJUNC); |
257 | static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_label, NULL, | 256 | static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, show_label, NULL, |
258 | DA9052_ADC_TJUNC); | 257 | DA9052_ADC_TJUNC); |
259 | 258 | ||
260 | static DEVICE_ATTR(name, S_IRUGO, da9052_hwmon_show_name, NULL); | 259 | static DEVICE_ATTR(name, S_IRUGO, da9052_hwmon_show_name, NULL); |
261 | 260 | ||
262 | static struct attribute *da9052_attr[] = { | 261 | static struct attribute *da9052_attr[] = { |
263 | &dev_attr_name.attr, | 262 | &dev_attr_name.attr, |
264 | &sensor_dev_attr_in0_input.dev_attr.attr, | 263 | &sensor_dev_attr_in0_input.dev_attr.attr, |
265 | &sensor_dev_attr_in0_label.dev_attr.attr, | 264 | &sensor_dev_attr_in0_label.dev_attr.attr, |
266 | &sensor_dev_attr_in3_input.dev_attr.attr, | 265 | &sensor_dev_attr_in3_input.dev_attr.attr, |
267 | &sensor_dev_attr_in3_label.dev_attr.attr, | 266 | &sensor_dev_attr_in3_label.dev_attr.attr, |
268 | &sensor_dev_attr_in4_input.dev_attr.attr, | 267 | &sensor_dev_attr_in4_input.dev_attr.attr, |
269 | &sensor_dev_attr_in4_label.dev_attr.attr, | 268 | &sensor_dev_attr_in4_label.dev_attr.attr, |
270 | &sensor_dev_attr_in5_input.dev_attr.attr, | 269 | &sensor_dev_attr_in5_input.dev_attr.attr, |
271 | &sensor_dev_attr_in5_label.dev_attr.attr, | 270 | &sensor_dev_attr_in5_label.dev_attr.attr, |
272 | &sensor_dev_attr_in6_input.dev_attr.attr, | 271 | &sensor_dev_attr_in6_input.dev_attr.attr, |
273 | &sensor_dev_attr_in6_label.dev_attr.attr, | 272 | &sensor_dev_attr_in6_label.dev_attr.attr, |
274 | &sensor_dev_attr_in9_input.dev_attr.attr, | 273 | &sensor_dev_attr_in9_input.dev_attr.attr, |
275 | &sensor_dev_attr_in9_label.dev_attr.attr, | 274 | &sensor_dev_attr_in9_label.dev_attr.attr, |
276 | &sensor_dev_attr_curr1_input.dev_attr.attr, | 275 | &sensor_dev_attr_curr1_input.dev_attr.attr, |
277 | &sensor_dev_attr_curr1_label.dev_attr.attr, | 276 | &sensor_dev_attr_curr1_label.dev_attr.attr, |
278 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 277 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
279 | &sensor_dev_attr_temp2_label.dev_attr.attr, | 278 | &sensor_dev_attr_temp2_label.dev_attr.attr, |
280 | &sensor_dev_attr_temp8_input.dev_attr.attr, | 279 | &sensor_dev_attr_temp8_input.dev_attr.attr, |
281 | &sensor_dev_attr_temp8_label.dev_attr.attr, | 280 | &sensor_dev_attr_temp8_label.dev_attr.attr, |
282 | NULL | 281 | NULL |
283 | }; | 282 | }; |
284 | 283 | ||
285 | static const struct attribute_group da9052_attr_group = {.attrs = da9052_attr}; | 284 | static const struct attribute_group da9052_attr_group = {.attrs = da9052_attr}; |
286 | 285 | ||
287 | static int __devinit da9052_hwmon_probe(struct platform_device *pdev) | 286 | static int __devinit da9052_hwmon_probe(struct platform_device *pdev) |
288 | { | 287 | { |
289 | struct da9052_hwmon *hwmon; | 288 | struct da9052_hwmon *hwmon; |
290 | int ret; | 289 | int ret; |
291 | 290 | ||
292 | hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9052_hwmon), | 291 | hwmon = devm_kzalloc(&pdev->dev, sizeof(struct da9052_hwmon), |
293 | GFP_KERNEL); | 292 | GFP_KERNEL); |
294 | if (!hwmon) | 293 | if (!hwmon) |
295 | return -ENOMEM; | 294 | return -ENOMEM; |
296 | 295 | ||
297 | mutex_init(&hwmon->hwmon_lock); | 296 | mutex_init(&hwmon->hwmon_lock); |
298 | hwmon->da9052 = dev_get_drvdata(pdev->dev.parent); | 297 | hwmon->da9052 = dev_get_drvdata(pdev->dev.parent); |
299 | 298 | ||
300 | platform_set_drvdata(pdev, hwmon); | 299 | platform_set_drvdata(pdev, hwmon); |
301 | 300 | ||
302 | ret = sysfs_create_group(&pdev->dev.kobj, &da9052_attr_group); | 301 | ret = sysfs_create_group(&pdev->dev.kobj, &da9052_attr_group); |
303 | if (ret) | 302 | if (ret) |
304 | goto err_mem; | 303 | goto err_mem; |
305 | 304 | ||
306 | hwmon->class_device = hwmon_device_register(&pdev->dev); | 305 | hwmon->class_device = hwmon_device_register(&pdev->dev); |
307 | if (IS_ERR(hwmon->class_device)) { | 306 | if (IS_ERR(hwmon->class_device)) { |
308 | ret = PTR_ERR(hwmon->class_device); | 307 | ret = PTR_ERR(hwmon->class_device); |
309 | goto err_sysfs; | 308 | goto err_sysfs; |
310 | } | 309 | } |
311 | 310 | ||
312 | return 0; | 311 | return 0; |
313 | 312 | ||
314 | err_sysfs: | 313 | err_sysfs: |
315 | sysfs_remove_group(&pdev->dev.kobj, &da9052_attr_group); | 314 | sysfs_remove_group(&pdev->dev.kobj, &da9052_attr_group); |
316 | err_mem: | 315 | err_mem: |
317 | return ret; | 316 | return ret; |
318 | } | 317 | } |
319 | 318 | ||
320 | static int __devexit da9052_hwmon_remove(struct platform_device *pdev) | 319 | static int __devexit da9052_hwmon_remove(struct platform_device *pdev) |
321 | { | 320 | { |
322 | struct da9052_hwmon *hwmon = platform_get_drvdata(pdev); | 321 | struct da9052_hwmon *hwmon = platform_get_drvdata(pdev); |
323 | 322 | ||
324 | hwmon_device_unregister(hwmon->class_device); | 323 | hwmon_device_unregister(hwmon->class_device); |
325 | sysfs_remove_group(&pdev->dev.kobj, &da9052_attr_group); | 324 | sysfs_remove_group(&pdev->dev.kobj, &da9052_attr_group); |
326 | 325 | ||
327 | return 0; | 326 | return 0; |
328 | } | 327 | } |
329 | 328 | ||
330 | static struct platform_driver da9052_hwmon_driver = { | 329 | static struct platform_driver da9052_hwmon_driver = { |
331 | .probe = da9052_hwmon_probe, | 330 | .probe = da9052_hwmon_probe, |
332 | .remove = __devexit_p(da9052_hwmon_remove), | 331 | .remove = __devexit_p(da9052_hwmon_remove), |
333 | .driver = { | 332 | .driver = { |
334 | .name = "da9052-hwmon", | 333 | .name = "da9052-hwmon", |
335 | .owner = THIS_MODULE, | 334 | .owner = THIS_MODULE, |
336 | }, | 335 | }, |
337 | }; | 336 | }; |
338 | 337 | ||
339 | module_platform_driver(da9052_hwmon_driver); | 338 | module_platform_driver(da9052_hwmon_driver); |
340 | 339 | ||
341 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); | 340 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); |
342 | MODULE_DESCRIPTION("DA9052 HWMON driver"); | 341 | MODULE_DESCRIPTION("DA9052 HWMON driver"); |
343 | MODULE_LICENSE("GPL"); | 342 | MODULE_LICENSE("GPL"); |
344 | MODULE_ALIAS("platform:da9052-hwmon"); | 343 | MODULE_ALIAS("platform:da9052-hwmon"); |
345 | 344 |
drivers/hwmon/emc6w201.c
1 | /* | 1 | /* |
2 | * emc6w201.c - Hardware monitoring driver for the SMSC EMC6W201 | 2 | * emc6w201.c - Hardware monitoring driver for the SMSC EMC6W201 |
3 | * Copyright (C) 2011 Jean Delvare <khali@linux-fr.org> | 3 | * Copyright (C) 2011 Jean Delvare <khali@linux-fr.org> |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
7 | * the Free Software Foundation; either version 2 of the License, or | 7 | * the Free Software Foundation; either version 2 of the License, or |
8 | * (at your option) any later version. | 8 | * (at your option) any later version. |
9 | * | 9 | * |
10 | * This program is distributed in the hope that it will be useful, | 10 | * This program is distributed in the hope that it will be useful, |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
13 | * GNU General Public License for more details. | 13 | * GNU General Public License for more details. |
14 | * | 14 | * |
15 | * You should have received a copy of the GNU General Public License | 15 | * You should have received a copy of the GNU General Public License |
16 | * along with this program; if not, write to the Free Software | 16 | * along with this program; if not, write to the Free Software |
17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 17 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include <linux/module.h> | 20 | #include <linux/module.h> |
21 | #include <linux/delay.h> | ||
22 | #include <linux/init.h> | 21 | #include <linux/init.h> |
23 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
24 | #include <linux/jiffies.h> | 23 | #include <linux/jiffies.h> |
25 | #include <linux/i2c.h> | 24 | #include <linux/i2c.h> |
26 | #include <linux/hwmon.h> | 25 | #include <linux/hwmon.h> |
27 | #include <linux/hwmon-sysfs.h> | 26 | #include <linux/hwmon-sysfs.h> |
28 | #include <linux/err.h> | 27 | #include <linux/err.h> |
29 | #include <linux/mutex.h> | 28 | #include <linux/mutex.h> |
30 | 29 | ||
31 | /* | 30 | /* |
32 | * Addresses to scan | 31 | * Addresses to scan |
33 | */ | 32 | */ |
34 | 33 | ||
35 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; | 34 | static const unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END }; |
36 | 35 | ||
37 | /* | 36 | /* |
38 | * The EMC6W201 registers | 37 | * The EMC6W201 registers |
39 | */ | 38 | */ |
40 | 39 | ||
41 | #define EMC6W201_REG_IN(nr) (0x20 + (nr)) | 40 | #define EMC6W201_REG_IN(nr) (0x20 + (nr)) |
42 | #define EMC6W201_REG_TEMP(nr) (0x26 + (nr)) | 41 | #define EMC6W201_REG_TEMP(nr) (0x26 + (nr)) |
43 | #define EMC6W201_REG_FAN(nr) (0x2C + (nr) * 2) | 42 | #define EMC6W201_REG_FAN(nr) (0x2C + (nr) * 2) |
44 | #define EMC6W201_REG_COMPANY 0x3E | 43 | #define EMC6W201_REG_COMPANY 0x3E |
45 | #define EMC6W201_REG_VERSTEP 0x3F | 44 | #define EMC6W201_REG_VERSTEP 0x3F |
46 | #define EMC6W201_REG_CONFIG 0x40 | 45 | #define EMC6W201_REG_CONFIG 0x40 |
47 | #define EMC6W201_REG_IN_LOW(nr) (0x4A + (nr) * 2) | 46 | #define EMC6W201_REG_IN_LOW(nr) (0x4A + (nr) * 2) |
48 | #define EMC6W201_REG_IN_HIGH(nr) (0x4B + (nr) * 2) | 47 | #define EMC6W201_REG_IN_HIGH(nr) (0x4B + (nr) * 2) |
49 | #define EMC6W201_REG_TEMP_LOW(nr) (0x56 + (nr) * 2) | 48 | #define EMC6W201_REG_TEMP_LOW(nr) (0x56 + (nr) * 2) |
50 | #define EMC6W201_REG_TEMP_HIGH(nr) (0x57 + (nr) * 2) | 49 | #define EMC6W201_REG_TEMP_HIGH(nr) (0x57 + (nr) * 2) |
51 | #define EMC6W201_REG_FAN_MIN(nr) (0x62 + (nr) * 2) | 50 | #define EMC6W201_REG_FAN_MIN(nr) (0x62 + (nr) * 2) |
52 | 51 | ||
53 | enum { input, min, max } subfeature; | 52 | enum { input, min, max } subfeature; |
54 | 53 | ||
55 | /* | 54 | /* |
56 | * Per-device data | 55 | * Per-device data |
57 | */ | 56 | */ |
58 | 57 | ||
59 | struct emc6w201_data { | 58 | struct emc6w201_data { |
60 | struct device *hwmon_dev; | 59 | struct device *hwmon_dev; |
61 | struct mutex update_lock; | 60 | struct mutex update_lock; |
62 | char valid; /* zero until following fields are valid */ | 61 | char valid; /* zero until following fields are valid */ |
63 | unsigned long last_updated; /* in jiffies */ | 62 | unsigned long last_updated; /* in jiffies */ |
64 | 63 | ||
65 | /* registers values */ | 64 | /* registers values */ |
66 | u8 in[3][6]; | 65 | u8 in[3][6]; |
67 | s8 temp[3][6]; | 66 | s8 temp[3][6]; |
68 | u16 fan[2][5]; | 67 | u16 fan[2][5]; |
69 | }; | 68 | }; |
70 | 69 | ||
71 | /* | 70 | /* |
72 | * Combine LSB and MSB registers in a single value | 71 | * Combine LSB and MSB registers in a single value |
73 | * Locking: must be called with data->update_lock held | 72 | * Locking: must be called with data->update_lock held |
74 | */ | 73 | */ |
75 | static u16 emc6w201_read16(struct i2c_client *client, u8 reg) | 74 | static u16 emc6w201_read16(struct i2c_client *client, u8 reg) |
76 | { | 75 | { |
77 | int lsb, msb; | 76 | int lsb, msb; |
78 | 77 | ||
79 | lsb = i2c_smbus_read_byte_data(client, reg); | 78 | lsb = i2c_smbus_read_byte_data(client, reg); |
80 | msb = i2c_smbus_read_byte_data(client, reg + 1); | 79 | msb = i2c_smbus_read_byte_data(client, reg + 1); |
81 | if (unlikely(lsb < 0 || msb < 0)) { | 80 | if (unlikely(lsb < 0 || msb < 0)) { |
82 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", | 81 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", |
83 | 16, "read", reg); | 82 | 16, "read", reg); |
84 | return 0xFFFF; /* Arbitrary value */ | 83 | return 0xFFFF; /* Arbitrary value */ |
85 | } | 84 | } |
86 | 85 | ||
87 | return (msb << 8) | lsb; | 86 | return (msb << 8) | lsb; |
88 | } | 87 | } |
89 | 88 | ||
90 | /* | 89 | /* |
91 | * Write 16-bit value to LSB and MSB registers | 90 | * Write 16-bit value to LSB and MSB registers |
92 | * Locking: must be called with data->update_lock held | 91 | * Locking: must be called with data->update_lock held |
93 | */ | 92 | */ |
94 | static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val) | 93 | static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val) |
95 | { | 94 | { |
96 | int err; | 95 | int err; |
97 | 96 | ||
98 | err = i2c_smbus_write_byte_data(client, reg, val & 0xff); | 97 | err = i2c_smbus_write_byte_data(client, reg, val & 0xff); |
99 | if (likely(!err)) | 98 | if (likely(!err)) |
100 | err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8); | 99 | err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8); |
101 | if (unlikely(err < 0)) | 100 | if (unlikely(err < 0)) |
102 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", | 101 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", |
103 | 16, "write", reg); | 102 | 16, "write", reg); |
104 | 103 | ||
105 | return err; | 104 | return err; |
106 | } | 105 | } |
107 | 106 | ||
108 | /* Read 8-bit value from register */ | 107 | /* Read 8-bit value from register */ |
109 | static u8 emc6w201_read8(struct i2c_client *client, u8 reg) | 108 | static u8 emc6w201_read8(struct i2c_client *client, u8 reg) |
110 | { | 109 | { |
111 | int val; | 110 | int val; |
112 | 111 | ||
113 | val = i2c_smbus_read_byte_data(client, reg); | 112 | val = i2c_smbus_read_byte_data(client, reg); |
114 | if (unlikely(val < 0)) { | 113 | if (unlikely(val < 0)) { |
115 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", | 114 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", |
116 | 8, "read", reg); | 115 | 8, "read", reg); |
117 | return 0x00; /* Arbitrary value */ | 116 | return 0x00; /* Arbitrary value */ |
118 | } | 117 | } |
119 | 118 | ||
120 | return val; | 119 | return val; |
121 | } | 120 | } |
122 | 121 | ||
123 | /* Write 8-bit value to register */ | 122 | /* Write 8-bit value to register */ |
124 | static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val) | 123 | static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val) |
125 | { | 124 | { |
126 | int err; | 125 | int err; |
127 | 126 | ||
128 | err = i2c_smbus_write_byte_data(client, reg, val); | 127 | err = i2c_smbus_write_byte_data(client, reg, val); |
129 | if (unlikely(err < 0)) | 128 | if (unlikely(err < 0)) |
130 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", | 129 | dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n", |
131 | 8, "write", reg); | 130 | 8, "write", reg); |
132 | 131 | ||
133 | return err; | 132 | return err; |
134 | } | 133 | } |
135 | 134 | ||
136 | static struct emc6w201_data *emc6w201_update_device(struct device *dev) | 135 | static struct emc6w201_data *emc6w201_update_device(struct device *dev) |
137 | { | 136 | { |
138 | struct i2c_client *client = to_i2c_client(dev); | 137 | struct i2c_client *client = to_i2c_client(dev); |
139 | struct emc6w201_data *data = i2c_get_clientdata(client); | 138 | struct emc6w201_data *data = i2c_get_clientdata(client); |
140 | int nr; | 139 | int nr; |
141 | 140 | ||
142 | mutex_lock(&data->update_lock); | 141 | mutex_lock(&data->update_lock); |
143 | 142 | ||
144 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 143 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
145 | for (nr = 0; nr < 6; nr++) { | 144 | for (nr = 0; nr < 6; nr++) { |
146 | data->in[input][nr] = | 145 | data->in[input][nr] = |
147 | emc6w201_read8(client, | 146 | emc6w201_read8(client, |
148 | EMC6W201_REG_IN(nr)); | 147 | EMC6W201_REG_IN(nr)); |
149 | data->in[min][nr] = | 148 | data->in[min][nr] = |
150 | emc6w201_read8(client, | 149 | emc6w201_read8(client, |
151 | EMC6W201_REG_IN_LOW(nr)); | 150 | EMC6W201_REG_IN_LOW(nr)); |
152 | data->in[max][nr] = | 151 | data->in[max][nr] = |
153 | emc6w201_read8(client, | 152 | emc6w201_read8(client, |
154 | EMC6W201_REG_IN_HIGH(nr)); | 153 | EMC6W201_REG_IN_HIGH(nr)); |
155 | } | 154 | } |
156 | 155 | ||
157 | for (nr = 0; nr < 6; nr++) { | 156 | for (nr = 0; nr < 6; nr++) { |
158 | data->temp[input][nr] = | 157 | data->temp[input][nr] = |
159 | emc6w201_read8(client, | 158 | emc6w201_read8(client, |
160 | EMC6W201_REG_TEMP(nr)); | 159 | EMC6W201_REG_TEMP(nr)); |
161 | data->temp[min][nr] = | 160 | data->temp[min][nr] = |
162 | emc6w201_read8(client, | 161 | emc6w201_read8(client, |
163 | EMC6W201_REG_TEMP_LOW(nr)); | 162 | EMC6W201_REG_TEMP_LOW(nr)); |
164 | data->temp[max][nr] = | 163 | data->temp[max][nr] = |
165 | emc6w201_read8(client, | 164 | emc6w201_read8(client, |
166 | EMC6W201_REG_TEMP_HIGH(nr)); | 165 | EMC6W201_REG_TEMP_HIGH(nr)); |
167 | } | 166 | } |
168 | 167 | ||
169 | for (nr = 0; nr < 5; nr++) { | 168 | for (nr = 0; nr < 5; nr++) { |
170 | data->fan[input][nr] = | 169 | data->fan[input][nr] = |
171 | emc6w201_read16(client, | 170 | emc6w201_read16(client, |
172 | EMC6W201_REG_FAN(nr)); | 171 | EMC6W201_REG_FAN(nr)); |
173 | data->fan[min][nr] = | 172 | data->fan[min][nr] = |
174 | emc6w201_read16(client, | 173 | emc6w201_read16(client, |
175 | EMC6W201_REG_FAN_MIN(nr)); | 174 | EMC6W201_REG_FAN_MIN(nr)); |
176 | } | 175 | } |
177 | 176 | ||
178 | data->last_updated = jiffies; | 177 | data->last_updated = jiffies; |
179 | data->valid = 1; | 178 | data->valid = 1; |
180 | } | 179 | } |
181 | 180 | ||
182 | mutex_unlock(&data->update_lock); | 181 | mutex_unlock(&data->update_lock); |
183 | 182 | ||
184 | return data; | 183 | return data; |
185 | } | 184 | } |
186 | 185 | ||
187 | /* | 186 | /* |
188 | * Sysfs callback functions | 187 | * Sysfs callback functions |
189 | */ | 188 | */ |
190 | 189 | ||
191 | static const u16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 }; | 190 | static const u16 nominal_mv[6] = { 2500, 1500, 3300, 5000, 1500, 1500 }; |
192 | 191 | ||
193 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, | 192 | static ssize_t show_in(struct device *dev, struct device_attribute *devattr, |
194 | char *buf) | 193 | char *buf) |
195 | { | 194 | { |
196 | struct emc6w201_data *data = emc6w201_update_device(dev); | 195 | struct emc6w201_data *data = emc6w201_update_device(dev); |
197 | int sf = to_sensor_dev_attr_2(devattr)->index; | 196 | int sf = to_sensor_dev_attr_2(devattr)->index; |
198 | int nr = to_sensor_dev_attr_2(devattr)->nr; | 197 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
199 | 198 | ||
200 | return sprintf(buf, "%u\n", | 199 | return sprintf(buf, "%u\n", |
201 | (unsigned)data->in[sf][nr] * nominal_mv[nr] / 0xC0); | 200 | (unsigned)data->in[sf][nr] * nominal_mv[nr] / 0xC0); |
202 | } | 201 | } |
203 | 202 | ||
204 | static ssize_t set_in(struct device *dev, struct device_attribute *devattr, | 203 | static ssize_t set_in(struct device *dev, struct device_attribute *devattr, |
205 | const char *buf, size_t count) | 204 | const char *buf, size_t count) |
206 | { | 205 | { |
207 | struct i2c_client *client = to_i2c_client(dev); | 206 | struct i2c_client *client = to_i2c_client(dev); |
208 | struct emc6w201_data *data = i2c_get_clientdata(client); | 207 | struct emc6w201_data *data = i2c_get_clientdata(client); |
209 | int sf = to_sensor_dev_attr_2(devattr)->index; | 208 | int sf = to_sensor_dev_attr_2(devattr)->index; |
210 | int nr = to_sensor_dev_attr_2(devattr)->nr; | 209 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
211 | int err; | 210 | int err; |
212 | long val; | 211 | long val; |
213 | u8 reg; | 212 | u8 reg; |
214 | 213 | ||
215 | err = kstrtol(buf, 10, &val); | 214 | err = kstrtol(buf, 10, &val); |
216 | if (err < 0) | 215 | if (err < 0) |
217 | return err; | 216 | return err; |
218 | 217 | ||
219 | val = DIV_ROUND_CLOSEST(val * 0xC0, nominal_mv[nr]); | 218 | val = DIV_ROUND_CLOSEST(val * 0xC0, nominal_mv[nr]); |
220 | reg = (sf == min) ? EMC6W201_REG_IN_LOW(nr) | 219 | reg = (sf == min) ? EMC6W201_REG_IN_LOW(nr) |
221 | : EMC6W201_REG_IN_HIGH(nr); | 220 | : EMC6W201_REG_IN_HIGH(nr); |
222 | 221 | ||
223 | mutex_lock(&data->update_lock); | 222 | mutex_lock(&data->update_lock); |
224 | data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255); | 223 | data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255); |
225 | err = emc6w201_write8(client, reg, data->in[sf][nr]); | 224 | err = emc6w201_write8(client, reg, data->in[sf][nr]); |
226 | mutex_unlock(&data->update_lock); | 225 | mutex_unlock(&data->update_lock); |
227 | 226 | ||
228 | return err < 0 ? err : count; | 227 | return err < 0 ? err : count; |
229 | } | 228 | } |
230 | 229 | ||
231 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, | 230 | static ssize_t show_temp(struct device *dev, struct device_attribute *devattr, |
232 | char *buf) | 231 | char *buf) |
233 | { | 232 | { |
234 | struct emc6w201_data *data = emc6w201_update_device(dev); | 233 | struct emc6w201_data *data = emc6w201_update_device(dev); |
235 | int sf = to_sensor_dev_attr_2(devattr)->index; | 234 | int sf = to_sensor_dev_attr_2(devattr)->index; |
236 | int nr = to_sensor_dev_attr_2(devattr)->nr; | 235 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
237 | 236 | ||
238 | return sprintf(buf, "%d\n", (int)data->temp[sf][nr] * 1000); | 237 | return sprintf(buf, "%d\n", (int)data->temp[sf][nr] * 1000); |
239 | } | 238 | } |
240 | 239 | ||
241 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, | 240 | static ssize_t set_temp(struct device *dev, struct device_attribute *devattr, |
242 | const char *buf, size_t count) | 241 | const char *buf, size_t count) |
243 | { | 242 | { |
244 | struct i2c_client *client = to_i2c_client(dev); | 243 | struct i2c_client *client = to_i2c_client(dev); |
245 | struct emc6w201_data *data = i2c_get_clientdata(client); | 244 | struct emc6w201_data *data = i2c_get_clientdata(client); |
246 | int sf = to_sensor_dev_attr_2(devattr)->index; | 245 | int sf = to_sensor_dev_attr_2(devattr)->index; |
247 | int nr = to_sensor_dev_attr_2(devattr)->nr; | 246 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
248 | int err; | 247 | int err; |
249 | long val; | 248 | long val; |
250 | u8 reg; | 249 | u8 reg; |
251 | 250 | ||
252 | err = kstrtol(buf, 10, &val); | 251 | err = kstrtol(buf, 10, &val); |
253 | if (err < 0) | 252 | if (err < 0) |
254 | return err; | 253 | return err; |
255 | 254 | ||
256 | val /= 1000; | 255 | val /= 1000; |
257 | reg = (sf == min) ? EMC6W201_REG_TEMP_LOW(nr) | 256 | reg = (sf == min) ? EMC6W201_REG_TEMP_LOW(nr) |
258 | : EMC6W201_REG_TEMP_HIGH(nr); | 257 | : EMC6W201_REG_TEMP_HIGH(nr); |
259 | 258 | ||
260 | mutex_lock(&data->update_lock); | 259 | mutex_lock(&data->update_lock); |
261 | data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128); | 260 | data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128); |
262 | err = emc6w201_write8(client, reg, data->temp[sf][nr]); | 261 | err = emc6w201_write8(client, reg, data->temp[sf][nr]); |
263 | mutex_unlock(&data->update_lock); | 262 | mutex_unlock(&data->update_lock); |
264 | 263 | ||
265 | return err < 0 ? err : count; | 264 | return err < 0 ? err : count; |
266 | } | 265 | } |
267 | 266 | ||
268 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, | 267 | static ssize_t show_fan(struct device *dev, struct device_attribute *devattr, |
269 | char *buf) | 268 | char *buf) |
270 | { | 269 | { |
271 | struct emc6w201_data *data = emc6w201_update_device(dev); | 270 | struct emc6w201_data *data = emc6w201_update_device(dev); |
272 | int sf = to_sensor_dev_attr_2(devattr)->index; | 271 | int sf = to_sensor_dev_attr_2(devattr)->index; |
273 | int nr = to_sensor_dev_attr_2(devattr)->nr; | 272 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
274 | unsigned rpm; | 273 | unsigned rpm; |
275 | 274 | ||
276 | if (data->fan[sf][nr] == 0 || data->fan[sf][nr] == 0xFFFF) | 275 | if (data->fan[sf][nr] == 0 || data->fan[sf][nr] == 0xFFFF) |
277 | rpm = 0; | 276 | rpm = 0; |
278 | else | 277 | else |
279 | rpm = 5400000U / data->fan[sf][nr]; | 278 | rpm = 5400000U / data->fan[sf][nr]; |
280 | 279 | ||
281 | return sprintf(buf, "%u\n", rpm); | 280 | return sprintf(buf, "%u\n", rpm); |
282 | } | 281 | } |
283 | 282 | ||
284 | static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, | 283 | static ssize_t set_fan(struct device *dev, struct device_attribute *devattr, |
285 | const char *buf, size_t count) | 284 | const char *buf, size_t count) |
286 | { | 285 | { |
287 | struct i2c_client *client = to_i2c_client(dev); | 286 | struct i2c_client *client = to_i2c_client(dev); |
288 | struct emc6w201_data *data = i2c_get_clientdata(client); | 287 | struct emc6w201_data *data = i2c_get_clientdata(client); |
289 | int sf = to_sensor_dev_attr_2(devattr)->index; | 288 | int sf = to_sensor_dev_attr_2(devattr)->index; |
290 | int nr = to_sensor_dev_attr_2(devattr)->nr; | 289 | int nr = to_sensor_dev_attr_2(devattr)->nr; |
291 | int err; | 290 | int err; |
292 | unsigned long val; | 291 | unsigned long val; |
293 | 292 | ||
294 | err = kstrtoul(buf, 10, &val); | 293 | err = kstrtoul(buf, 10, &val); |
295 | if (err < 0) | 294 | if (err < 0) |
296 | return err; | 295 | return err; |
297 | 296 | ||
298 | if (val == 0) { | 297 | if (val == 0) { |
299 | val = 0xFFFF; | 298 | val = 0xFFFF; |
300 | } else { | 299 | } else { |
301 | val = DIV_ROUND_CLOSEST(5400000U, val); | 300 | val = DIV_ROUND_CLOSEST(5400000U, val); |
302 | val = SENSORS_LIMIT(val, 0, 0xFFFE); | 301 | val = SENSORS_LIMIT(val, 0, 0xFFFE); |
303 | } | 302 | } |
304 | 303 | ||
305 | mutex_lock(&data->update_lock); | 304 | mutex_lock(&data->update_lock); |
306 | data->fan[sf][nr] = val; | 305 | data->fan[sf][nr] = val; |
307 | err = emc6w201_write16(client, EMC6W201_REG_FAN_MIN(nr), | 306 | err = emc6w201_write16(client, EMC6W201_REG_FAN_MIN(nr), |
308 | data->fan[sf][nr]); | 307 | data->fan[sf][nr]); |
309 | mutex_unlock(&data->update_lock); | 308 | mutex_unlock(&data->update_lock); |
310 | 309 | ||
311 | return err < 0 ? err : count; | 310 | return err < 0 ? err : count; |
312 | } | 311 | } |
313 | 312 | ||
314 | static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, input); | 313 | static SENSOR_DEVICE_ATTR_2(in0_input, S_IRUGO, show_in, NULL, 0, input); |
315 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in, | 314 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IRUGO | S_IWUSR, show_in, set_in, |
316 | 0, min); | 315 | 0, min); |
317 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in, | 316 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IRUGO | S_IWUSR, show_in, set_in, |
318 | 0, max); | 317 | 0, max); |
319 | static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, input); | 318 | static SENSOR_DEVICE_ATTR_2(in1_input, S_IRUGO, show_in, NULL, 1, input); |
320 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in, | 319 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IRUGO | S_IWUSR, show_in, set_in, |
321 | 1, min); | 320 | 1, min); |
322 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in, | 321 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IRUGO | S_IWUSR, show_in, set_in, |
323 | 1, max); | 322 | 1, max); |
324 | static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, input); | 323 | static SENSOR_DEVICE_ATTR_2(in2_input, S_IRUGO, show_in, NULL, 2, input); |
325 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in, | 324 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IRUGO | S_IWUSR, show_in, set_in, |
326 | 2, min); | 325 | 2, min); |
327 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in, | 326 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IRUGO | S_IWUSR, show_in, set_in, |
328 | 2, max); | 327 | 2, max); |
329 | static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, input); | 328 | static SENSOR_DEVICE_ATTR_2(in3_input, S_IRUGO, show_in, NULL, 3, input); |
330 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in, | 329 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IRUGO | S_IWUSR, show_in, set_in, |
331 | 3, min); | 330 | 3, min); |
332 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in, | 331 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IRUGO | S_IWUSR, show_in, set_in, |
333 | 3, max); | 332 | 3, max); |
334 | static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, input); | 333 | static SENSOR_DEVICE_ATTR_2(in4_input, S_IRUGO, show_in, NULL, 4, input); |
335 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in, | 334 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IRUGO | S_IWUSR, show_in, set_in, |
336 | 4, min); | 335 | 4, min); |
337 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in, | 336 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IRUGO | S_IWUSR, show_in, set_in, |
338 | 4, max); | 337 | 4, max); |
339 | static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, input); | 338 | static SENSOR_DEVICE_ATTR_2(in5_input, S_IRUGO, show_in, NULL, 5, input); |
340 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in, | 339 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IRUGO | S_IWUSR, show_in, set_in, |
341 | 5, min); | 340 | 5, min); |
342 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in, | 341 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IRUGO | S_IWUSR, show_in, set_in, |
343 | 5, max); | 342 | 5, max); |
344 | 343 | ||
345 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, input); | 344 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, input); |
346 | static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp, | 345 | static SENSOR_DEVICE_ATTR_2(temp1_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
347 | 0, min); | 346 | 0, min); |
348 | static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | 347 | static SENSOR_DEVICE_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp, set_temp, |
349 | 0, max); | 348 | 0, max); |
350 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, input); | 349 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 1, input); |
351 | static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp, | 350 | static SENSOR_DEVICE_ATTR_2(temp2_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
352 | 1, min); | 351 | 1, min); |
353 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | 352 | static SENSOR_DEVICE_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp, set_temp, |
354 | 1, max); | 353 | 1, max); |
355 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, input); | 354 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 2, input); |
356 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp, | 355 | static SENSOR_DEVICE_ATTR_2(temp3_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
357 | 2, min); | 356 | 2, min); |
358 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | 357 | static SENSOR_DEVICE_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp, set_temp, |
359 | 2, max); | 358 | 2, max); |
360 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, input); | 359 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 3, input); |
361 | static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp, | 360 | static SENSOR_DEVICE_ATTR_2(temp4_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
362 | 3, min); | 361 | 3, min); |
363 | static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | 362 | static SENSOR_DEVICE_ATTR_2(temp4_max, S_IRUGO | S_IWUSR, show_temp, set_temp, |
364 | 3, max); | 363 | 3, max); |
365 | static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, input); | 364 | static SENSOR_DEVICE_ATTR_2(temp5_input, S_IRUGO, show_temp, NULL, 4, input); |
366 | static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp, | 365 | static SENSOR_DEVICE_ATTR_2(temp5_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
367 | 4, min); | 366 | 4, min); |
368 | static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | 367 | static SENSOR_DEVICE_ATTR_2(temp5_max, S_IRUGO | S_IWUSR, show_temp, set_temp, |
369 | 4, max); | 368 | 4, max); |
370 | static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, input); | 369 | static SENSOR_DEVICE_ATTR_2(temp6_input, S_IRUGO, show_temp, NULL, 5, input); |
371 | static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp, | 370 | static SENSOR_DEVICE_ATTR_2(temp6_min, S_IRUGO | S_IWUSR, show_temp, set_temp, |
372 | 5, min); | 371 | 5, min); |
373 | static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp, | 372 | static SENSOR_DEVICE_ATTR_2(temp6_max, S_IRUGO | S_IWUSR, show_temp, set_temp, |
374 | 5, max); | 373 | 5, max); |
375 | 374 | ||
376 | static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, input); | 375 | static SENSOR_DEVICE_ATTR_2(fan1_input, S_IRUGO, show_fan, NULL, 0, input); |
377 | static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | 376 | static SENSOR_DEVICE_ATTR_2(fan1_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
378 | 0, min); | 377 | 0, min); |
379 | static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, input); | 378 | static SENSOR_DEVICE_ATTR_2(fan2_input, S_IRUGO, show_fan, NULL, 1, input); |
380 | static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | 379 | static SENSOR_DEVICE_ATTR_2(fan2_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
381 | 1, min); | 380 | 1, min); |
382 | static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, input); | 381 | static SENSOR_DEVICE_ATTR_2(fan3_input, S_IRUGO, show_fan, NULL, 2, input); |
383 | static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | 382 | static SENSOR_DEVICE_ATTR_2(fan3_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
384 | 2, min); | 383 | 2, min); |
385 | static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, input); | 384 | static SENSOR_DEVICE_ATTR_2(fan4_input, S_IRUGO, show_fan, NULL, 3, input); |
386 | static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | 385 | static SENSOR_DEVICE_ATTR_2(fan4_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
387 | 3, min); | 386 | 3, min); |
388 | static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, input); | 387 | static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, input); |
389 | static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan, | 388 | static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan, |
390 | 4, min); | 389 | 4, min); |
391 | 390 | ||
392 | static struct attribute *emc6w201_attributes[] = { | 391 | static struct attribute *emc6w201_attributes[] = { |
393 | &sensor_dev_attr_in0_input.dev_attr.attr, | 392 | &sensor_dev_attr_in0_input.dev_attr.attr, |
394 | &sensor_dev_attr_in0_min.dev_attr.attr, | 393 | &sensor_dev_attr_in0_min.dev_attr.attr, |
395 | &sensor_dev_attr_in0_max.dev_attr.attr, | 394 | &sensor_dev_attr_in0_max.dev_attr.attr, |
396 | &sensor_dev_attr_in1_input.dev_attr.attr, | 395 | &sensor_dev_attr_in1_input.dev_attr.attr, |
397 | &sensor_dev_attr_in1_min.dev_attr.attr, | 396 | &sensor_dev_attr_in1_min.dev_attr.attr, |
398 | &sensor_dev_attr_in1_max.dev_attr.attr, | 397 | &sensor_dev_attr_in1_max.dev_attr.attr, |
399 | &sensor_dev_attr_in2_input.dev_attr.attr, | 398 | &sensor_dev_attr_in2_input.dev_attr.attr, |
400 | &sensor_dev_attr_in2_min.dev_attr.attr, | 399 | &sensor_dev_attr_in2_min.dev_attr.attr, |
401 | &sensor_dev_attr_in2_max.dev_attr.attr, | 400 | &sensor_dev_attr_in2_max.dev_attr.attr, |
402 | &sensor_dev_attr_in3_input.dev_attr.attr, | 401 | &sensor_dev_attr_in3_input.dev_attr.attr, |
403 | &sensor_dev_attr_in3_min.dev_attr.attr, | 402 | &sensor_dev_attr_in3_min.dev_attr.attr, |
404 | &sensor_dev_attr_in3_max.dev_attr.attr, | 403 | &sensor_dev_attr_in3_max.dev_attr.attr, |
405 | &sensor_dev_attr_in4_input.dev_attr.attr, | 404 | &sensor_dev_attr_in4_input.dev_attr.attr, |
406 | &sensor_dev_attr_in4_min.dev_attr.attr, | 405 | &sensor_dev_attr_in4_min.dev_attr.attr, |
407 | &sensor_dev_attr_in4_max.dev_attr.attr, | 406 | &sensor_dev_attr_in4_max.dev_attr.attr, |
408 | &sensor_dev_attr_in5_input.dev_attr.attr, | 407 | &sensor_dev_attr_in5_input.dev_attr.attr, |
409 | &sensor_dev_attr_in5_min.dev_attr.attr, | 408 | &sensor_dev_attr_in5_min.dev_attr.attr, |
410 | &sensor_dev_attr_in5_max.dev_attr.attr, | 409 | &sensor_dev_attr_in5_max.dev_attr.attr, |
411 | 410 | ||
412 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 411 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
413 | &sensor_dev_attr_temp1_min.dev_attr.attr, | 412 | &sensor_dev_attr_temp1_min.dev_attr.attr, |
414 | &sensor_dev_attr_temp1_max.dev_attr.attr, | 413 | &sensor_dev_attr_temp1_max.dev_attr.attr, |
415 | &sensor_dev_attr_temp2_input.dev_attr.attr, | 414 | &sensor_dev_attr_temp2_input.dev_attr.attr, |
416 | &sensor_dev_attr_temp2_min.dev_attr.attr, | 415 | &sensor_dev_attr_temp2_min.dev_attr.attr, |
417 | &sensor_dev_attr_temp2_max.dev_attr.attr, | 416 | &sensor_dev_attr_temp2_max.dev_attr.attr, |
418 | &sensor_dev_attr_temp3_input.dev_attr.attr, | 417 | &sensor_dev_attr_temp3_input.dev_attr.attr, |
419 | &sensor_dev_attr_temp3_min.dev_attr.attr, | 418 | &sensor_dev_attr_temp3_min.dev_attr.attr, |
420 | &sensor_dev_attr_temp3_max.dev_attr.attr, | 419 | &sensor_dev_attr_temp3_max.dev_attr.attr, |
421 | &sensor_dev_attr_temp4_input.dev_attr.attr, | 420 | &sensor_dev_attr_temp4_input.dev_attr.attr, |
422 | &sensor_dev_attr_temp4_min.dev_attr.attr, | 421 | &sensor_dev_attr_temp4_min.dev_attr.attr, |
423 | &sensor_dev_attr_temp4_max.dev_attr.attr, | 422 | &sensor_dev_attr_temp4_max.dev_attr.attr, |
424 | &sensor_dev_attr_temp5_input.dev_attr.attr, | 423 | &sensor_dev_attr_temp5_input.dev_attr.attr, |
425 | &sensor_dev_attr_temp5_min.dev_attr.attr, | 424 | &sensor_dev_attr_temp5_min.dev_attr.attr, |
426 | &sensor_dev_attr_temp5_max.dev_attr.attr, | 425 | &sensor_dev_attr_temp5_max.dev_attr.attr, |
427 | &sensor_dev_attr_temp6_input.dev_attr.attr, | 426 | &sensor_dev_attr_temp6_input.dev_attr.attr, |
428 | &sensor_dev_attr_temp6_min.dev_attr.attr, | 427 | &sensor_dev_attr_temp6_min.dev_attr.attr, |
429 | &sensor_dev_attr_temp6_max.dev_attr.attr, | 428 | &sensor_dev_attr_temp6_max.dev_attr.attr, |
430 | 429 | ||
431 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 430 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
432 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 431 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
433 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 432 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
434 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 433 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
435 | &sensor_dev_attr_fan3_input.dev_attr.attr, | 434 | &sensor_dev_attr_fan3_input.dev_attr.attr, |
436 | &sensor_dev_attr_fan3_min.dev_attr.attr, | 435 | &sensor_dev_attr_fan3_min.dev_attr.attr, |
437 | &sensor_dev_attr_fan4_input.dev_attr.attr, | 436 | &sensor_dev_attr_fan4_input.dev_attr.attr, |
438 | &sensor_dev_attr_fan4_min.dev_attr.attr, | 437 | &sensor_dev_attr_fan4_min.dev_attr.attr, |
439 | &sensor_dev_attr_fan5_input.dev_attr.attr, | 438 | &sensor_dev_attr_fan5_input.dev_attr.attr, |
440 | &sensor_dev_attr_fan5_min.dev_attr.attr, | 439 | &sensor_dev_attr_fan5_min.dev_attr.attr, |
441 | NULL | 440 | NULL |
442 | }; | 441 | }; |
443 | 442 | ||
444 | static const struct attribute_group emc6w201_group = { | 443 | static const struct attribute_group emc6w201_group = { |
445 | .attrs = emc6w201_attributes, | 444 | .attrs = emc6w201_attributes, |
446 | }; | 445 | }; |
447 | 446 | ||
448 | /* | 447 | /* |
449 | * Driver interface | 448 | * Driver interface |
450 | */ | 449 | */ |
451 | 450 | ||
452 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 451 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
453 | static int emc6w201_detect(struct i2c_client *client, | 452 | static int emc6w201_detect(struct i2c_client *client, |
454 | struct i2c_board_info *info) | 453 | struct i2c_board_info *info) |
455 | { | 454 | { |
456 | struct i2c_adapter *adapter = client->adapter; | 455 | struct i2c_adapter *adapter = client->adapter; |
457 | int company, verstep, config; | 456 | int company, verstep, config; |
458 | 457 | ||
459 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 458 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
460 | return -ENODEV; | 459 | return -ENODEV; |
461 | 460 | ||
462 | /* Identification */ | 461 | /* Identification */ |
463 | company = i2c_smbus_read_byte_data(client, EMC6W201_REG_COMPANY); | 462 | company = i2c_smbus_read_byte_data(client, EMC6W201_REG_COMPANY); |
464 | if (company != 0x5C) | 463 | if (company != 0x5C) |
465 | return -ENODEV; | 464 | return -ENODEV; |
466 | verstep = i2c_smbus_read_byte_data(client, EMC6W201_REG_VERSTEP); | 465 | verstep = i2c_smbus_read_byte_data(client, EMC6W201_REG_VERSTEP); |
467 | if (verstep < 0 || (verstep & 0xF0) != 0xB0) | 466 | if (verstep < 0 || (verstep & 0xF0) != 0xB0) |
468 | return -ENODEV; | 467 | return -ENODEV; |
469 | if ((verstep & 0x0F) > 2) { | 468 | if ((verstep & 0x0F) > 2) { |
470 | dev_dbg(&client->dev, "Unknwown EMC6W201 stepping %d\n", | 469 | dev_dbg(&client->dev, "Unknwown EMC6W201 stepping %d\n", |
471 | verstep & 0x0F); | 470 | verstep & 0x0F); |
472 | return -ENODEV; | 471 | return -ENODEV; |
473 | } | 472 | } |
474 | 473 | ||
475 | /* Check configuration */ | 474 | /* Check configuration */ |
476 | config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG); | 475 | config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG); |
477 | if (config < 0 || (config & 0xF4) != 0x04) | 476 | if (config < 0 || (config & 0xF4) != 0x04) |
478 | return -ENODEV; | 477 | return -ENODEV; |
479 | if (!(config & 0x01)) { | 478 | if (!(config & 0x01)) { |
480 | dev_err(&client->dev, "Monitoring not enabled\n"); | 479 | dev_err(&client->dev, "Monitoring not enabled\n"); |
481 | return -ENODEV; | 480 | return -ENODEV; |
482 | } | 481 | } |
483 | 482 | ||
484 | strlcpy(info->type, "emc6w201", I2C_NAME_SIZE); | 483 | strlcpy(info->type, "emc6w201", I2C_NAME_SIZE); |
485 | 484 | ||
486 | return 0; | 485 | return 0; |
487 | } | 486 | } |
488 | 487 | ||
489 | static int emc6w201_probe(struct i2c_client *client, | 488 | static int emc6w201_probe(struct i2c_client *client, |
490 | const struct i2c_device_id *id) | 489 | const struct i2c_device_id *id) |
491 | { | 490 | { |
492 | struct emc6w201_data *data; | 491 | struct emc6w201_data *data; |
493 | int err; | 492 | int err; |
494 | 493 | ||
495 | data = devm_kzalloc(&client->dev, sizeof(struct emc6w201_data), | 494 | data = devm_kzalloc(&client->dev, sizeof(struct emc6w201_data), |
496 | GFP_KERNEL); | 495 | GFP_KERNEL); |
497 | if (!data) | 496 | if (!data) |
498 | return -ENOMEM; | 497 | return -ENOMEM; |
499 | 498 | ||
500 | i2c_set_clientdata(client, data); | 499 | i2c_set_clientdata(client, data); |
501 | mutex_init(&data->update_lock); | 500 | mutex_init(&data->update_lock); |
502 | 501 | ||
503 | /* Create sysfs attribute */ | 502 | /* Create sysfs attribute */ |
504 | err = sysfs_create_group(&client->dev.kobj, &emc6w201_group); | 503 | err = sysfs_create_group(&client->dev.kobj, &emc6w201_group); |
505 | if (err) | 504 | if (err) |
506 | return err; | 505 | return err; |
507 | 506 | ||
508 | /* Expose as a hwmon device */ | 507 | /* Expose as a hwmon device */ |
509 | data->hwmon_dev = hwmon_device_register(&client->dev); | 508 | data->hwmon_dev = hwmon_device_register(&client->dev); |
510 | if (IS_ERR(data->hwmon_dev)) { | 509 | if (IS_ERR(data->hwmon_dev)) { |
511 | err = PTR_ERR(data->hwmon_dev); | 510 | err = PTR_ERR(data->hwmon_dev); |
512 | goto exit_remove; | 511 | goto exit_remove; |
513 | } | 512 | } |
514 | 513 | ||
515 | return 0; | 514 | return 0; |
516 | 515 | ||
517 | exit_remove: | 516 | exit_remove: |
518 | sysfs_remove_group(&client->dev.kobj, &emc6w201_group); | 517 | sysfs_remove_group(&client->dev.kobj, &emc6w201_group); |
519 | return err; | 518 | return err; |
520 | } | 519 | } |
521 | 520 | ||
522 | static int emc6w201_remove(struct i2c_client *client) | 521 | static int emc6w201_remove(struct i2c_client *client) |
523 | { | 522 | { |
524 | struct emc6w201_data *data = i2c_get_clientdata(client); | 523 | struct emc6w201_data *data = i2c_get_clientdata(client); |
525 | 524 | ||
526 | hwmon_device_unregister(data->hwmon_dev); | 525 | hwmon_device_unregister(data->hwmon_dev); |
527 | sysfs_remove_group(&client->dev.kobj, &emc6w201_group); | 526 | sysfs_remove_group(&client->dev.kobj, &emc6w201_group); |
528 | 527 | ||
529 | return 0; | 528 | return 0; |
530 | } | 529 | } |
531 | 530 | ||
532 | static const struct i2c_device_id emc6w201_id[] = { | 531 | static const struct i2c_device_id emc6w201_id[] = { |
533 | { "emc6w201", 0 }, | 532 | { "emc6w201", 0 }, |
534 | { } | 533 | { } |
535 | }; | 534 | }; |
536 | MODULE_DEVICE_TABLE(i2c, emc6w201_id); | 535 | MODULE_DEVICE_TABLE(i2c, emc6w201_id); |
537 | 536 | ||
538 | static struct i2c_driver emc6w201_driver = { | 537 | static struct i2c_driver emc6w201_driver = { |
539 | .class = I2C_CLASS_HWMON, | 538 | .class = I2C_CLASS_HWMON, |
540 | .driver = { | 539 | .driver = { |
541 | .name = "emc6w201", | 540 | .name = "emc6w201", |
542 | }, | 541 | }, |
543 | .probe = emc6w201_probe, | 542 | .probe = emc6w201_probe, |
544 | .remove = emc6w201_remove, | 543 | .remove = emc6w201_remove, |
545 | .id_table = emc6w201_id, | 544 | .id_table = emc6w201_id, |
546 | .detect = emc6w201_detect, | 545 | .detect = emc6w201_detect, |
547 | .address_list = normal_i2c, | 546 | .address_list = normal_i2c, |
548 | }; | 547 | }; |
549 | 548 | ||
550 | module_i2c_driver(emc6w201_driver); | 549 | module_i2c_driver(emc6w201_driver); |
551 | 550 | ||
552 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); | 551 | MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>"); |
553 | MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver"); | 552 | MODULE_DESCRIPTION("SMSC EMC6W201 hardware monitoring driver"); |
554 | MODULE_LICENSE("GPL"); | 553 | MODULE_LICENSE("GPL"); |
555 | 554 |
drivers/hwmon/i5k_amb.c
1 | /* | 1 | /* |
2 | * A hwmon driver for the Intel 5000 series chipset FB-DIMM AMB | 2 | * A hwmon driver for the Intel 5000 series chipset FB-DIMM AMB |
3 | * temperature sensors | 3 | * temperature sensors |
4 | * Copyright (C) 2007 IBM | 4 | * Copyright (C) 2007 IBM |
5 | * | 5 | * |
6 | * Author: Darrick J. Wong <djwong@us.ibm.com> | 6 | * Author: Darrick J. Wong <djwong@us.ibm.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/hwmon.h> | 24 | #include <linux/hwmon.h> |
25 | #include <linux/hwmon-sysfs.h> | 25 | #include <linux/hwmon-sysfs.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/mutex.h> | 27 | #include <linux/mutex.h> |
28 | #include <linux/delay.h> | ||
29 | #include <linux/log2.h> | 28 | #include <linux/log2.h> |
30 | #include <linux/pci.h> | 29 | #include <linux/pci.h> |
31 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
33 | 32 | ||
34 | #define DRVNAME "i5k_amb" | 33 | #define DRVNAME "i5k_amb" |
35 | 34 | ||
36 | #define I5K_REG_AMB_BASE_ADDR 0x48 | 35 | #define I5K_REG_AMB_BASE_ADDR 0x48 |
37 | #define I5K_REG_AMB_LEN_ADDR 0x50 | 36 | #define I5K_REG_AMB_LEN_ADDR 0x50 |
38 | #define I5K_REG_CHAN0_PRESENCE_ADDR 0x64 | 37 | #define I5K_REG_CHAN0_PRESENCE_ADDR 0x64 |
39 | #define I5K_REG_CHAN1_PRESENCE_ADDR 0x66 | 38 | #define I5K_REG_CHAN1_PRESENCE_ADDR 0x66 |
40 | 39 | ||
41 | #define AMB_REG_TEMP_MIN_ADDR 0x80 | 40 | #define AMB_REG_TEMP_MIN_ADDR 0x80 |
42 | #define AMB_REG_TEMP_MID_ADDR 0x81 | 41 | #define AMB_REG_TEMP_MID_ADDR 0x81 |
43 | #define AMB_REG_TEMP_MAX_ADDR 0x82 | 42 | #define AMB_REG_TEMP_MAX_ADDR 0x82 |
44 | #define AMB_REG_TEMP_STATUS_ADDR 0x84 | 43 | #define AMB_REG_TEMP_STATUS_ADDR 0x84 |
45 | #define AMB_REG_TEMP_ADDR 0x85 | 44 | #define AMB_REG_TEMP_ADDR 0x85 |
46 | 45 | ||
47 | #define AMB_CONFIG_SIZE 2048 | 46 | #define AMB_CONFIG_SIZE 2048 |
48 | #define AMB_FUNC_3_OFFSET 768 | 47 | #define AMB_FUNC_3_OFFSET 768 |
49 | 48 | ||
50 | static unsigned long amb_reg_temp_status(unsigned int amb) | 49 | static unsigned long amb_reg_temp_status(unsigned int amb) |
51 | { | 50 | { |
52 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_STATUS_ADDR + | 51 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_STATUS_ADDR + |
53 | AMB_CONFIG_SIZE * amb; | 52 | AMB_CONFIG_SIZE * amb; |
54 | } | 53 | } |
55 | 54 | ||
56 | static unsigned long amb_reg_temp_min(unsigned int amb) | 55 | static unsigned long amb_reg_temp_min(unsigned int amb) |
57 | { | 56 | { |
58 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MIN_ADDR + | 57 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MIN_ADDR + |
59 | AMB_CONFIG_SIZE * amb; | 58 | AMB_CONFIG_SIZE * amb; |
60 | } | 59 | } |
61 | 60 | ||
62 | static unsigned long amb_reg_temp_mid(unsigned int amb) | 61 | static unsigned long amb_reg_temp_mid(unsigned int amb) |
63 | { | 62 | { |
64 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MID_ADDR + | 63 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MID_ADDR + |
65 | AMB_CONFIG_SIZE * amb; | 64 | AMB_CONFIG_SIZE * amb; |
66 | } | 65 | } |
67 | 66 | ||
68 | static unsigned long amb_reg_temp_max(unsigned int amb) | 67 | static unsigned long amb_reg_temp_max(unsigned int amb) |
69 | { | 68 | { |
70 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MAX_ADDR + | 69 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MAX_ADDR + |
71 | AMB_CONFIG_SIZE * amb; | 70 | AMB_CONFIG_SIZE * amb; |
72 | } | 71 | } |
73 | 72 | ||
74 | static unsigned long amb_reg_temp(unsigned int amb) | 73 | static unsigned long amb_reg_temp(unsigned int amb) |
75 | { | 74 | { |
76 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_ADDR + | 75 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_ADDR + |
77 | AMB_CONFIG_SIZE * amb; | 76 | AMB_CONFIG_SIZE * amb; |
78 | } | 77 | } |
79 | 78 | ||
80 | #define MAX_MEM_CHANNELS 4 | 79 | #define MAX_MEM_CHANNELS 4 |
81 | #define MAX_AMBS_PER_CHANNEL 16 | 80 | #define MAX_AMBS_PER_CHANNEL 16 |
82 | #define MAX_AMBS (MAX_MEM_CHANNELS * \ | 81 | #define MAX_AMBS (MAX_MEM_CHANNELS * \ |
83 | MAX_AMBS_PER_CHANNEL) | 82 | MAX_AMBS_PER_CHANNEL) |
84 | #define CHANNEL_SHIFT 4 | 83 | #define CHANNEL_SHIFT 4 |
85 | #define DIMM_MASK 0xF | 84 | #define DIMM_MASK 0xF |
86 | /* | 85 | /* |
87 | * Ugly hack: For some reason the highest bit is set if there | 86 | * Ugly hack: For some reason the highest bit is set if there |
88 | * are _any_ DIMMs in the channel. Attempting to read from | 87 | * are _any_ DIMMs in the channel. Attempting to read from |
89 | * this "high-order" AMB results in a memory bus error, so | 88 | * this "high-order" AMB results in a memory bus error, so |
90 | * for now we'll just ignore that top bit, even though that | 89 | * for now we'll just ignore that top bit, even though that |
91 | * might prevent us from seeing the 16th DIMM in the channel. | 90 | * might prevent us from seeing the 16th DIMM in the channel. |
92 | */ | 91 | */ |
93 | #define REAL_MAX_AMBS_PER_CHANNEL 15 | 92 | #define REAL_MAX_AMBS_PER_CHANNEL 15 |
94 | #define KNOBS_PER_AMB 6 | 93 | #define KNOBS_PER_AMB 6 |
95 | 94 | ||
96 | static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) | 95 | static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) |
97 | { | 96 | { |
98 | return byte_num * MAX_AMBS_PER_CHANNEL + bit; | 97 | return byte_num * MAX_AMBS_PER_CHANNEL + bit; |
99 | } | 98 | } |
100 | 99 | ||
101 | #define AMB_SYSFS_NAME_LEN 16 | 100 | #define AMB_SYSFS_NAME_LEN 16 |
102 | struct i5k_device_attribute { | 101 | struct i5k_device_attribute { |
103 | struct sensor_device_attribute s_attr; | 102 | struct sensor_device_attribute s_attr; |
104 | char name[AMB_SYSFS_NAME_LEN]; | 103 | char name[AMB_SYSFS_NAME_LEN]; |
105 | }; | 104 | }; |
106 | 105 | ||
107 | struct i5k_amb_data { | 106 | struct i5k_amb_data { |
108 | struct device *hwmon_dev; | 107 | struct device *hwmon_dev; |
109 | 108 | ||
110 | unsigned long amb_base; | 109 | unsigned long amb_base; |
111 | unsigned long amb_len; | 110 | unsigned long amb_len; |
112 | u16 amb_present[MAX_MEM_CHANNELS]; | 111 | u16 amb_present[MAX_MEM_CHANNELS]; |
113 | void __iomem *amb_mmio; | 112 | void __iomem *amb_mmio; |
114 | struct i5k_device_attribute *attrs; | 113 | struct i5k_device_attribute *attrs; |
115 | unsigned int num_attrs; | 114 | unsigned int num_attrs; |
116 | }; | 115 | }; |
117 | 116 | ||
118 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | 117 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, |
119 | char *buf) | 118 | char *buf) |
120 | { | 119 | { |
121 | return sprintf(buf, "%s\n", DRVNAME); | 120 | return sprintf(buf, "%s\n", DRVNAME); |
122 | } | 121 | } |
123 | 122 | ||
124 | 123 | ||
125 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 124 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
126 | 125 | ||
127 | static struct platform_device *amb_pdev; | 126 | static struct platform_device *amb_pdev; |
128 | 127 | ||
129 | static u8 amb_read_byte(struct i5k_amb_data *data, unsigned long offset) | 128 | static u8 amb_read_byte(struct i5k_amb_data *data, unsigned long offset) |
130 | { | 129 | { |
131 | return ioread8(data->amb_mmio + offset); | 130 | return ioread8(data->amb_mmio + offset); |
132 | } | 131 | } |
133 | 132 | ||
134 | static void amb_write_byte(struct i5k_amb_data *data, unsigned long offset, | 133 | static void amb_write_byte(struct i5k_amb_data *data, unsigned long offset, |
135 | u8 val) | 134 | u8 val) |
136 | { | 135 | { |
137 | iowrite8(val, data->amb_mmio + offset); | 136 | iowrite8(val, data->amb_mmio + offset); |
138 | } | 137 | } |
139 | 138 | ||
140 | static ssize_t show_amb_alarm(struct device *dev, | 139 | static ssize_t show_amb_alarm(struct device *dev, |
141 | struct device_attribute *devattr, | 140 | struct device_attribute *devattr, |
142 | char *buf) | 141 | char *buf) |
143 | { | 142 | { |
144 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 143 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
145 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 144 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
146 | 145 | ||
147 | if (!(amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x20) && | 146 | if (!(amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x20) && |
148 | (amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x8)) | 147 | (amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x8)) |
149 | return sprintf(buf, "1\n"); | 148 | return sprintf(buf, "1\n"); |
150 | else | 149 | else |
151 | return sprintf(buf, "0\n"); | 150 | return sprintf(buf, "0\n"); |
152 | } | 151 | } |
153 | 152 | ||
154 | static ssize_t store_amb_min(struct device *dev, | 153 | static ssize_t store_amb_min(struct device *dev, |
155 | struct device_attribute *devattr, | 154 | struct device_attribute *devattr, |
156 | const char *buf, | 155 | const char *buf, |
157 | size_t count) | 156 | size_t count) |
158 | { | 157 | { |
159 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 158 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
160 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 159 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
161 | unsigned long temp; | 160 | unsigned long temp; |
162 | int ret = kstrtoul(buf, 10, &temp); | 161 | int ret = kstrtoul(buf, 10, &temp); |
163 | if (ret < 0) | 162 | if (ret < 0) |
164 | return ret; | 163 | return ret; |
165 | 164 | ||
166 | temp = temp / 500; | 165 | temp = temp / 500; |
167 | if (temp > 255) | 166 | if (temp > 255) |
168 | temp = 255; | 167 | temp = 255; |
169 | 168 | ||
170 | amb_write_byte(data, amb_reg_temp_min(attr->index), temp); | 169 | amb_write_byte(data, amb_reg_temp_min(attr->index), temp); |
171 | return count; | 170 | return count; |
172 | } | 171 | } |
173 | 172 | ||
174 | static ssize_t store_amb_mid(struct device *dev, | 173 | static ssize_t store_amb_mid(struct device *dev, |
175 | struct device_attribute *devattr, | 174 | struct device_attribute *devattr, |
176 | const char *buf, | 175 | const char *buf, |
177 | size_t count) | 176 | size_t count) |
178 | { | 177 | { |
179 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 178 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
180 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 179 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
181 | unsigned long temp; | 180 | unsigned long temp; |
182 | int ret = kstrtoul(buf, 10, &temp); | 181 | int ret = kstrtoul(buf, 10, &temp); |
183 | if (ret < 0) | 182 | if (ret < 0) |
184 | return ret; | 183 | return ret; |
185 | 184 | ||
186 | temp = temp / 500; | 185 | temp = temp / 500; |
187 | if (temp > 255) | 186 | if (temp > 255) |
188 | temp = 255; | 187 | temp = 255; |
189 | 188 | ||
190 | amb_write_byte(data, amb_reg_temp_mid(attr->index), temp); | 189 | amb_write_byte(data, amb_reg_temp_mid(attr->index), temp); |
191 | return count; | 190 | return count; |
192 | } | 191 | } |
193 | 192 | ||
194 | static ssize_t store_amb_max(struct device *dev, | 193 | static ssize_t store_amb_max(struct device *dev, |
195 | struct device_attribute *devattr, | 194 | struct device_attribute *devattr, |
196 | const char *buf, | 195 | const char *buf, |
197 | size_t count) | 196 | size_t count) |
198 | { | 197 | { |
199 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 198 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
200 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 199 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
201 | unsigned long temp; | 200 | unsigned long temp; |
202 | int ret = kstrtoul(buf, 10, &temp); | 201 | int ret = kstrtoul(buf, 10, &temp); |
203 | if (ret < 0) | 202 | if (ret < 0) |
204 | return ret; | 203 | return ret; |
205 | 204 | ||
206 | temp = temp / 500; | 205 | temp = temp / 500; |
207 | if (temp > 255) | 206 | if (temp > 255) |
208 | temp = 255; | 207 | temp = 255; |
209 | 208 | ||
210 | amb_write_byte(data, amb_reg_temp_max(attr->index), temp); | 209 | amb_write_byte(data, amb_reg_temp_max(attr->index), temp); |
211 | return count; | 210 | return count; |
212 | } | 211 | } |
213 | 212 | ||
214 | static ssize_t show_amb_min(struct device *dev, | 213 | static ssize_t show_amb_min(struct device *dev, |
215 | struct device_attribute *devattr, | 214 | struct device_attribute *devattr, |
216 | char *buf) | 215 | char *buf) |
217 | { | 216 | { |
218 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 217 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
219 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 218 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
220 | return sprintf(buf, "%d\n", | 219 | return sprintf(buf, "%d\n", |
221 | 500 * amb_read_byte(data, amb_reg_temp_min(attr->index))); | 220 | 500 * amb_read_byte(data, amb_reg_temp_min(attr->index))); |
222 | } | 221 | } |
223 | 222 | ||
224 | static ssize_t show_amb_mid(struct device *dev, | 223 | static ssize_t show_amb_mid(struct device *dev, |
225 | struct device_attribute *devattr, | 224 | struct device_attribute *devattr, |
226 | char *buf) | 225 | char *buf) |
227 | { | 226 | { |
228 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 227 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
229 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 228 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
230 | return sprintf(buf, "%d\n", | 229 | return sprintf(buf, "%d\n", |
231 | 500 * amb_read_byte(data, amb_reg_temp_mid(attr->index))); | 230 | 500 * amb_read_byte(data, amb_reg_temp_mid(attr->index))); |
232 | } | 231 | } |
233 | 232 | ||
234 | static ssize_t show_amb_max(struct device *dev, | 233 | static ssize_t show_amb_max(struct device *dev, |
235 | struct device_attribute *devattr, | 234 | struct device_attribute *devattr, |
236 | char *buf) | 235 | char *buf) |
237 | { | 236 | { |
238 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 237 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
239 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 238 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
240 | return sprintf(buf, "%d\n", | 239 | return sprintf(buf, "%d\n", |
241 | 500 * amb_read_byte(data, amb_reg_temp_max(attr->index))); | 240 | 500 * amb_read_byte(data, amb_reg_temp_max(attr->index))); |
242 | } | 241 | } |
243 | 242 | ||
244 | static ssize_t show_amb_temp(struct device *dev, | 243 | static ssize_t show_amb_temp(struct device *dev, |
245 | struct device_attribute *devattr, | 244 | struct device_attribute *devattr, |
246 | char *buf) | 245 | char *buf) |
247 | { | 246 | { |
248 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 247 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
249 | struct i5k_amb_data *data = dev_get_drvdata(dev); | 248 | struct i5k_amb_data *data = dev_get_drvdata(dev); |
250 | return sprintf(buf, "%d\n", | 249 | return sprintf(buf, "%d\n", |
251 | 500 * amb_read_byte(data, amb_reg_temp(attr->index))); | 250 | 500 * amb_read_byte(data, amb_reg_temp(attr->index))); |
252 | } | 251 | } |
253 | 252 | ||
254 | static ssize_t show_label(struct device *dev, | 253 | static ssize_t show_label(struct device *dev, |
255 | struct device_attribute *devattr, | 254 | struct device_attribute *devattr, |
256 | char *buf) | 255 | char *buf) |
257 | { | 256 | { |
258 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 257 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
259 | 258 | ||
260 | return sprintf(buf, "Ch. %d DIMM %d\n", attr->index >> CHANNEL_SHIFT, | 259 | return sprintf(buf, "Ch. %d DIMM %d\n", attr->index >> CHANNEL_SHIFT, |
261 | attr->index & DIMM_MASK); | 260 | attr->index & DIMM_MASK); |
262 | } | 261 | } |
263 | 262 | ||
264 | static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) | 263 | static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) |
265 | { | 264 | { |
266 | int i, j, k, d = 0; | 265 | int i, j, k, d = 0; |
267 | u16 c; | 266 | u16 c; |
268 | int res = 0; | 267 | int res = 0; |
269 | int num_ambs = 0; | 268 | int num_ambs = 0; |
270 | struct i5k_amb_data *data = platform_get_drvdata(pdev); | 269 | struct i5k_amb_data *data = platform_get_drvdata(pdev); |
271 | 270 | ||
272 | /* Count the number of AMBs found */ | 271 | /* Count the number of AMBs found */ |
273 | /* ignore the high-order bit, see "Ugly hack" comment above */ | 272 | /* ignore the high-order bit, see "Ugly hack" comment above */ |
274 | for (i = 0; i < MAX_MEM_CHANNELS; i++) | 273 | for (i = 0; i < MAX_MEM_CHANNELS; i++) |
275 | num_ambs += hweight16(data->amb_present[i] & 0x7fff); | 274 | num_ambs += hweight16(data->amb_present[i] & 0x7fff); |
276 | 275 | ||
277 | /* Set up sysfs stuff */ | 276 | /* Set up sysfs stuff */ |
278 | data->attrs = kzalloc(sizeof(*data->attrs) * num_ambs * KNOBS_PER_AMB, | 277 | data->attrs = kzalloc(sizeof(*data->attrs) * num_ambs * KNOBS_PER_AMB, |
279 | GFP_KERNEL); | 278 | GFP_KERNEL); |
280 | if (!data->attrs) | 279 | if (!data->attrs) |
281 | return -ENOMEM; | 280 | return -ENOMEM; |
282 | data->num_attrs = 0; | 281 | data->num_attrs = 0; |
283 | 282 | ||
284 | for (i = 0; i < MAX_MEM_CHANNELS; i++) { | 283 | for (i = 0; i < MAX_MEM_CHANNELS; i++) { |
285 | c = data->amb_present[i]; | 284 | c = data->amb_present[i]; |
286 | for (j = 0; j < REAL_MAX_AMBS_PER_CHANNEL; j++, c >>= 1) { | 285 | for (j = 0; j < REAL_MAX_AMBS_PER_CHANNEL; j++, c >>= 1) { |
287 | struct i5k_device_attribute *iattr; | 286 | struct i5k_device_attribute *iattr; |
288 | 287 | ||
289 | k = amb_num_from_reg(i, j); | 288 | k = amb_num_from_reg(i, j); |
290 | if (!(c & 0x1)) | 289 | if (!(c & 0x1)) |
291 | continue; | 290 | continue; |
292 | d++; | 291 | d++; |
293 | 292 | ||
294 | /* sysfs label */ | 293 | /* sysfs label */ |
295 | iattr = data->attrs + data->num_attrs; | 294 | iattr = data->attrs + data->num_attrs; |
296 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 295 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
297 | "temp%d_label", d); | 296 | "temp%d_label", d); |
298 | iattr->s_attr.dev_attr.attr.name = iattr->name; | 297 | iattr->s_attr.dev_attr.attr.name = iattr->name; |
299 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; | 298 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; |
300 | iattr->s_attr.dev_attr.show = show_label; | 299 | iattr->s_attr.dev_attr.show = show_label; |
301 | iattr->s_attr.index = k; | 300 | iattr->s_attr.index = k; |
302 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); | 301 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); |
303 | res = device_create_file(&pdev->dev, | 302 | res = device_create_file(&pdev->dev, |
304 | &iattr->s_attr.dev_attr); | 303 | &iattr->s_attr.dev_attr); |
305 | if (res) | 304 | if (res) |
306 | goto exit_remove; | 305 | goto exit_remove; |
307 | data->num_attrs++; | 306 | data->num_attrs++; |
308 | 307 | ||
309 | /* Temperature sysfs knob */ | 308 | /* Temperature sysfs knob */ |
310 | iattr = data->attrs + data->num_attrs; | 309 | iattr = data->attrs + data->num_attrs; |
311 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 310 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
312 | "temp%d_input", d); | 311 | "temp%d_input", d); |
313 | iattr->s_attr.dev_attr.attr.name = iattr->name; | 312 | iattr->s_attr.dev_attr.attr.name = iattr->name; |
314 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; | 313 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; |
315 | iattr->s_attr.dev_attr.show = show_amb_temp; | 314 | iattr->s_attr.dev_attr.show = show_amb_temp; |
316 | iattr->s_attr.index = k; | 315 | iattr->s_attr.index = k; |
317 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); | 316 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); |
318 | res = device_create_file(&pdev->dev, | 317 | res = device_create_file(&pdev->dev, |
319 | &iattr->s_attr.dev_attr); | 318 | &iattr->s_attr.dev_attr); |
320 | if (res) | 319 | if (res) |
321 | goto exit_remove; | 320 | goto exit_remove; |
322 | data->num_attrs++; | 321 | data->num_attrs++; |
323 | 322 | ||
324 | /* Temperature min sysfs knob */ | 323 | /* Temperature min sysfs knob */ |
325 | iattr = data->attrs + data->num_attrs; | 324 | iattr = data->attrs + data->num_attrs; |
326 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 325 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
327 | "temp%d_min", d); | 326 | "temp%d_min", d); |
328 | iattr->s_attr.dev_attr.attr.name = iattr->name; | 327 | iattr->s_attr.dev_attr.attr.name = iattr->name; |
329 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; | 328 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; |
330 | iattr->s_attr.dev_attr.show = show_amb_min; | 329 | iattr->s_attr.dev_attr.show = show_amb_min; |
331 | iattr->s_attr.dev_attr.store = store_amb_min; | 330 | iattr->s_attr.dev_attr.store = store_amb_min; |
332 | iattr->s_attr.index = k; | 331 | iattr->s_attr.index = k; |
333 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); | 332 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); |
334 | res = device_create_file(&pdev->dev, | 333 | res = device_create_file(&pdev->dev, |
335 | &iattr->s_attr.dev_attr); | 334 | &iattr->s_attr.dev_attr); |
336 | if (res) | 335 | if (res) |
337 | goto exit_remove; | 336 | goto exit_remove; |
338 | data->num_attrs++; | 337 | data->num_attrs++; |
339 | 338 | ||
340 | /* Temperature mid sysfs knob */ | 339 | /* Temperature mid sysfs knob */ |
341 | iattr = data->attrs + data->num_attrs; | 340 | iattr = data->attrs + data->num_attrs; |
342 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 341 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
343 | "temp%d_mid", d); | 342 | "temp%d_mid", d); |
344 | iattr->s_attr.dev_attr.attr.name = iattr->name; | 343 | iattr->s_attr.dev_attr.attr.name = iattr->name; |
345 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; | 344 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; |
346 | iattr->s_attr.dev_attr.show = show_amb_mid; | 345 | iattr->s_attr.dev_attr.show = show_amb_mid; |
347 | iattr->s_attr.dev_attr.store = store_amb_mid; | 346 | iattr->s_attr.dev_attr.store = store_amb_mid; |
348 | iattr->s_attr.index = k; | 347 | iattr->s_attr.index = k; |
349 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); | 348 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); |
350 | res = device_create_file(&pdev->dev, | 349 | res = device_create_file(&pdev->dev, |
351 | &iattr->s_attr.dev_attr); | 350 | &iattr->s_attr.dev_attr); |
352 | if (res) | 351 | if (res) |
353 | goto exit_remove; | 352 | goto exit_remove; |
354 | data->num_attrs++; | 353 | data->num_attrs++; |
355 | 354 | ||
356 | /* Temperature max sysfs knob */ | 355 | /* Temperature max sysfs knob */ |
357 | iattr = data->attrs + data->num_attrs; | 356 | iattr = data->attrs + data->num_attrs; |
358 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 357 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
359 | "temp%d_max", d); | 358 | "temp%d_max", d); |
360 | iattr->s_attr.dev_attr.attr.name = iattr->name; | 359 | iattr->s_attr.dev_attr.attr.name = iattr->name; |
361 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; | 360 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; |
362 | iattr->s_attr.dev_attr.show = show_amb_max; | 361 | iattr->s_attr.dev_attr.show = show_amb_max; |
363 | iattr->s_attr.dev_attr.store = store_amb_max; | 362 | iattr->s_attr.dev_attr.store = store_amb_max; |
364 | iattr->s_attr.index = k; | 363 | iattr->s_attr.index = k; |
365 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); | 364 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); |
366 | res = device_create_file(&pdev->dev, | 365 | res = device_create_file(&pdev->dev, |
367 | &iattr->s_attr.dev_attr); | 366 | &iattr->s_attr.dev_attr); |
368 | if (res) | 367 | if (res) |
369 | goto exit_remove; | 368 | goto exit_remove; |
370 | data->num_attrs++; | 369 | data->num_attrs++; |
371 | 370 | ||
372 | /* Temperature alarm sysfs knob */ | 371 | /* Temperature alarm sysfs knob */ |
373 | iattr = data->attrs + data->num_attrs; | 372 | iattr = data->attrs + data->num_attrs; |
374 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | 373 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, |
375 | "temp%d_alarm", d); | 374 | "temp%d_alarm", d); |
376 | iattr->s_attr.dev_attr.attr.name = iattr->name; | 375 | iattr->s_attr.dev_attr.attr.name = iattr->name; |
377 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; | 376 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; |
378 | iattr->s_attr.dev_attr.show = show_amb_alarm; | 377 | iattr->s_attr.dev_attr.show = show_amb_alarm; |
379 | iattr->s_attr.index = k; | 378 | iattr->s_attr.index = k; |
380 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); | 379 | sysfs_attr_init(&iattr->s_attr.dev_attr.attr); |
381 | res = device_create_file(&pdev->dev, | 380 | res = device_create_file(&pdev->dev, |
382 | &iattr->s_attr.dev_attr); | 381 | &iattr->s_attr.dev_attr); |
383 | if (res) | 382 | if (res) |
384 | goto exit_remove; | 383 | goto exit_remove; |
385 | data->num_attrs++; | 384 | data->num_attrs++; |
386 | } | 385 | } |
387 | } | 386 | } |
388 | 387 | ||
389 | res = device_create_file(&pdev->dev, &dev_attr_name); | 388 | res = device_create_file(&pdev->dev, &dev_attr_name); |
390 | if (res) | 389 | if (res) |
391 | goto exit_remove; | 390 | goto exit_remove; |
392 | 391 | ||
393 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 392 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
394 | if (IS_ERR(data->hwmon_dev)) { | 393 | if (IS_ERR(data->hwmon_dev)) { |
395 | res = PTR_ERR(data->hwmon_dev); | 394 | res = PTR_ERR(data->hwmon_dev); |
396 | goto exit_remove; | 395 | goto exit_remove; |
397 | } | 396 | } |
398 | 397 | ||
399 | return res; | 398 | return res; |
400 | 399 | ||
401 | exit_remove: | 400 | exit_remove: |
402 | device_remove_file(&pdev->dev, &dev_attr_name); | 401 | device_remove_file(&pdev->dev, &dev_attr_name); |
403 | for (i = 0; i < data->num_attrs; i++) | 402 | for (i = 0; i < data->num_attrs; i++) |
404 | device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr); | 403 | device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr); |
405 | kfree(data->attrs); | 404 | kfree(data->attrs); |
406 | 405 | ||
407 | return res; | 406 | return res; |
408 | } | 407 | } |
409 | 408 | ||
410 | static int __devinit i5k_amb_add(void) | 409 | static int __devinit i5k_amb_add(void) |
411 | { | 410 | { |
412 | int res = -ENODEV; | 411 | int res = -ENODEV; |
413 | 412 | ||
414 | /* only ever going to be one of these */ | 413 | /* only ever going to be one of these */ |
415 | amb_pdev = platform_device_alloc(DRVNAME, 0); | 414 | amb_pdev = platform_device_alloc(DRVNAME, 0); |
416 | if (!amb_pdev) | 415 | if (!amb_pdev) |
417 | return -ENOMEM; | 416 | return -ENOMEM; |
418 | 417 | ||
419 | res = platform_device_add(amb_pdev); | 418 | res = platform_device_add(amb_pdev); |
420 | if (res) | 419 | if (res) |
421 | goto err; | 420 | goto err; |
422 | return 0; | 421 | return 0; |
423 | 422 | ||
424 | err: | 423 | err: |
425 | platform_device_put(amb_pdev); | 424 | platform_device_put(amb_pdev); |
426 | return res; | 425 | return res; |
427 | } | 426 | } |
428 | 427 | ||
429 | static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data, | 428 | static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data, |
430 | unsigned long devid) | 429 | unsigned long devid) |
431 | { | 430 | { |
432 | struct pci_dev *pcidev; | 431 | struct pci_dev *pcidev; |
433 | u32 val32; | 432 | u32 val32; |
434 | int res = -ENODEV; | 433 | int res = -ENODEV; |
435 | 434 | ||
436 | /* Find AMB register memory space */ | 435 | /* Find AMB register memory space */ |
437 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | 436 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, |
438 | devid, | 437 | devid, |
439 | NULL); | 438 | NULL); |
440 | if (!pcidev) | 439 | if (!pcidev) |
441 | return -ENODEV; | 440 | return -ENODEV; |
442 | 441 | ||
443 | if (pci_read_config_dword(pcidev, I5K_REG_AMB_BASE_ADDR, &val32)) | 442 | if (pci_read_config_dword(pcidev, I5K_REG_AMB_BASE_ADDR, &val32)) |
444 | goto out; | 443 | goto out; |
445 | data->amb_base = val32; | 444 | data->amb_base = val32; |
446 | 445 | ||
447 | if (pci_read_config_dword(pcidev, I5K_REG_AMB_LEN_ADDR, &val32)) | 446 | if (pci_read_config_dword(pcidev, I5K_REG_AMB_LEN_ADDR, &val32)) |
448 | goto out; | 447 | goto out; |
449 | data->amb_len = val32; | 448 | data->amb_len = val32; |
450 | 449 | ||
451 | /* Is it big enough? */ | 450 | /* Is it big enough? */ |
452 | if (data->amb_len < AMB_CONFIG_SIZE * MAX_AMBS) { | 451 | if (data->amb_len < AMB_CONFIG_SIZE * MAX_AMBS) { |
453 | dev_err(&pcidev->dev, "AMB region too small!\n"); | 452 | dev_err(&pcidev->dev, "AMB region too small!\n"); |
454 | goto out; | 453 | goto out; |
455 | } | 454 | } |
456 | 455 | ||
457 | res = 0; | 456 | res = 0; |
458 | out: | 457 | out: |
459 | pci_dev_put(pcidev); | 458 | pci_dev_put(pcidev); |
460 | return res; | 459 | return res; |
461 | } | 460 | } |
462 | 461 | ||
463 | static int __devinit i5k_channel_probe(u16 *amb_present, unsigned long dev_id) | 462 | static int __devinit i5k_channel_probe(u16 *amb_present, unsigned long dev_id) |
464 | { | 463 | { |
465 | struct pci_dev *pcidev; | 464 | struct pci_dev *pcidev; |
466 | u16 val16; | 465 | u16 val16; |
467 | int res = -ENODEV; | 466 | int res = -ENODEV; |
468 | 467 | ||
469 | /* Copy the DIMM presence map for these two channels */ | 468 | /* Copy the DIMM presence map for these two channels */ |
470 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); | 469 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); |
471 | if (!pcidev) | 470 | if (!pcidev) |
472 | return -ENODEV; | 471 | return -ENODEV; |
473 | 472 | ||
474 | if (pci_read_config_word(pcidev, I5K_REG_CHAN0_PRESENCE_ADDR, &val16)) | 473 | if (pci_read_config_word(pcidev, I5K_REG_CHAN0_PRESENCE_ADDR, &val16)) |
475 | goto out; | 474 | goto out; |
476 | amb_present[0] = val16; | 475 | amb_present[0] = val16; |
477 | 476 | ||
478 | if (pci_read_config_word(pcidev, I5K_REG_CHAN1_PRESENCE_ADDR, &val16)) | 477 | if (pci_read_config_word(pcidev, I5K_REG_CHAN1_PRESENCE_ADDR, &val16)) |
479 | goto out; | 478 | goto out; |
480 | amb_present[1] = val16; | 479 | amb_present[1] = val16; |
481 | 480 | ||
482 | res = 0; | 481 | res = 0; |
483 | 482 | ||
484 | out: | 483 | out: |
485 | pci_dev_put(pcidev); | 484 | pci_dev_put(pcidev); |
486 | return res; | 485 | return res; |
487 | } | 486 | } |
488 | 487 | ||
489 | static struct { | 488 | static struct { |
490 | unsigned long err; | 489 | unsigned long err; |
491 | unsigned long fbd0; | 490 | unsigned long fbd0; |
492 | } chipset_ids[] __devinitdata = { | 491 | } chipset_ids[] __devinitdata = { |
493 | { PCI_DEVICE_ID_INTEL_5000_ERR, PCI_DEVICE_ID_INTEL_5000_FBD0 }, | 492 | { PCI_DEVICE_ID_INTEL_5000_ERR, PCI_DEVICE_ID_INTEL_5000_FBD0 }, |
494 | { PCI_DEVICE_ID_INTEL_5400_ERR, PCI_DEVICE_ID_INTEL_5400_FBD0 }, | 493 | { PCI_DEVICE_ID_INTEL_5400_ERR, PCI_DEVICE_ID_INTEL_5400_FBD0 }, |
495 | { 0, 0 } | 494 | { 0, 0 } |
496 | }; | 495 | }; |
497 | 496 | ||
498 | #ifdef MODULE | 497 | #ifdef MODULE |
499 | static struct pci_device_id i5k_amb_ids[] __devinitdata = { | 498 | static struct pci_device_id i5k_amb_ids[] __devinitdata = { |
500 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, | 499 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5000_ERR) }, |
501 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) }, | 500 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_5400_ERR) }, |
502 | { 0, } | 501 | { 0, } |
503 | }; | 502 | }; |
504 | MODULE_DEVICE_TABLE(pci, i5k_amb_ids); | 503 | MODULE_DEVICE_TABLE(pci, i5k_amb_ids); |
505 | #endif | 504 | #endif |
506 | 505 | ||
507 | static int __devinit i5k_amb_probe(struct platform_device *pdev) | 506 | static int __devinit i5k_amb_probe(struct platform_device *pdev) |
508 | { | 507 | { |
509 | struct i5k_amb_data *data; | 508 | struct i5k_amb_data *data; |
510 | struct resource *reso; | 509 | struct resource *reso; |
511 | int i, res; | 510 | int i, res; |
512 | 511 | ||
513 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 512 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
514 | if (!data) | 513 | if (!data) |
515 | return -ENOMEM; | 514 | return -ENOMEM; |
516 | 515 | ||
517 | /* Figure out where the AMB registers live */ | 516 | /* Figure out where the AMB registers live */ |
518 | i = 0; | 517 | i = 0; |
519 | do { | 518 | do { |
520 | res = i5k_find_amb_registers(data, chipset_ids[i].err); | 519 | res = i5k_find_amb_registers(data, chipset_ids[i].err); |
521 | if (res == 0) | 520 | if (res == 0) |
522 | break; | 521 | break; |
523 | i++; | 522 | i++; |
524 | } while (chipset_ids[i].err); | 523 | } while (chipset_ids[i].err); |
525 | 524 | ||
526 | if (res) | 525 | if (res) |
527 | goto err; | 526 | goto err; |
528 | 527 | ||
529 | /* Copy the DIMM presence map for the first two channels */ | 528 | /* Copy the DIMM presence map for the first two channels */ |
530 | res = i5k_channel_probe(&data->amb_present[0], chipset_ids[i].fbd0); | 529 | res = i5k_channel_probe(&data->amb_present[0], chipset_ids[i].fbd0); |
531 | if (res) | 530 | if (res) |
532 | goto err; | 531 | goto err; |
533 | 532 | ||
534 | /* Copy the DIMM presence map for the optional second two channels */ | 533 | /* Copy the DIMM presence map for the optional second two channels */ |
535 | i5k_channel_probe(&data->amb_present[2], chipset_ids[i].fbd0 + 1); | 534 | i5k_channel_probe(&data->amb_present[2], chipset_ids[i].fbd0 + 1); |
536 | 535 | ||
537 | /* Set up resource regions */ | 536 | /* Set up resource regions */ |
538 | reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); | 537 | reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); |
539 | if (!reso) { | 538 | if (!reso) { |
540 | res = -EBUSY; | 539 | res = -EBUSY; |
541 | goto err; | 540 | goto err; |
542 | } | 541 | } |
543 | 542 | ||
544 | data->amb_mmio = ioremap_nocache(data->amb_base, data->amb_len); | 543 | data->amb_mmio = ioremap_nocache(data->amb_base, data->amb_len); |
545 | if (!data->amb_mmio) { | 544 | if (!data->amb_mmio) { |
546 | res = -EBUSY; | 545 | res = -EBUSY; |
547 | goto err_map_failed; | 546 | goto err_map_failed; |
548 | } | 547 | } |
549 | 548 | ||
550 | platform_set_drvdata(pdev, data); | 549 | platform_set_drvdata(pdev, data); |
551 | 550 | ||
552 | res = i5k_amb_hwmon_init(pdev); | 551 | res = i5k_amb_hwmon_init(pdev); |
553 | if (res) | 552 | if (res) |
554 | goto err_init_failed; | 553 | goto err_init_failed; |
555 | 554 | ||
556 | return res; | 555 | return res; |
557 | 556 | ||
558 | err_init_failed: | 557 | err_init_failed: |
559 | iounmap(data->amb_mmio); | 558 | iounmap(data->amb_mmio); |
560 | platform_set_drvdata(pdev, NULL); | 559 | platform_set_drvdata(pdev, NULL); |
561 | err_map_failed: | 560 | err_map_failed: |
562 | release_mem_region(data->amb_base, data->amb_len); | 561 | release_mem_region(data->amb_base, data->amb_len); |
563 | err: | 562 | err: |
564 | kfree(data); | 563 | kfree(data); |
565 | return res; | 564 | return res; |
566 | } | 565 | } |
567 | 566 | ||
568 | static int __devexit i5k_amb_remove(struct platform_device *pdev) | 567 | static int __devexit i5k_amb_remove(struct platform_device *pdev) |
569 | { | 568 | { |
570 | int i; | 569 | int i; |
571 | struct i5k_amb_data *data = platform_get_drvdata(pdev); | 570 | struct i5k_amb_data *data = platform_get_drvdata(pdev); |
572 | 571 | ||
573 | hwmon_device_unregister(data->hwmon_dev); | 572 | hwmon_device_unregister(data->hwmon_dev); |
574 | device_remove_file(&pdev->dev, &dev_attr_name); | 573 | device_remove_file(&pdev->dev, &dev_attr_name); |
575 | for (i = 0; i < data->num_attrs; i++) | 574 | for (i = 0; i < data->num_attrs; i++) |
576 | device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr); | 575 | device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr); |
577 | kfree(data->attrs); | 576 | kfree(data->attrs); |
578 | iounmap(data->amb_mmio); | 577 | iounmap(data->amb_mmio); |
579 | release_mem_region(data->amb_base, data->amb_len); | 578 | release_mem_region(data->amb_base, data->amb_len); |
580 | platform_set_drvdata(pdev, NULL); | 579 | platform_set_drvdata(pdev, NULL); |
581 | kfree(data); | 580 | kfree(data); |
582 | return 0; | 581 | return 0; |
583 | } | 582 | } |
584 | 583 | ||
585 | static struct platform_driver i5k_amb_driver = { | 584 | static struct platform_driver i5k_amb_driver = { |
586 | .driver = { | 585 | .driver = { |
587 | .owner = THIS_MODULE, | 586 | .owner = THIS_MODULE, |
588 | .name = DRVNAME, | 587 | .name = DRVNAME, |
589 | }, | 588 | }, |
590 | .probe = i5k_amb_probe, | 589 | .probe = i5k_amb_probe, |
591 | .remove = __devexit_p(i5k_amb_remove), | 590 | .remove = __devexit_p(i5k_amb_remove), |
592 | }; | 591 | }; |
593 | 592 | ||
594 | static int __init i5k_amb_init(void) | 593 | static int __init i5k_amb_init(void) |
595 | { | 594 | { |
596 | int res; | 595 | int res; |
597 | 596 | ||
598 | res = platform_driver_register(&i5k_amb_driver); | 597 | res = platform_driver_register(&i5k_amb_driver); |
599 | if (res) | 598 | if (res) |
600 | return res; | 599 | return res; |
601 | 600 | ||
602 | res = i5k_amb_add(); | 601 | res = i5k_amb_add(); |
603 | if (res) | 602 | if (res) |
604 | platform_driver_unregister(&i5k_amb_driver); | 603 | platform_driver_unregister(&i5k_amb_driver); |
605 | 604 | ||
606 | return res; | 605 | return res; |
607 | } | 606 | } |
608 | 607 | ||
609 | static void __exit i5k_amb_exit(void) | 608 | static void __exit i5k_amb_exit(void) |
610 | { | 609 | { |
611 | platform_device_unregister(amb_pdev); | 610 | platform_device_unregister(amb_pdev); |
612 | platform_driver_unregister(&i5k_amb_driver); | 611 | platform_driver_unregister(&i5k_amb_driver); |
613 | } | 612 | } |
614 | 613 | ||
615 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | 614 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); |
616 | MODULE_DESCRIPTION("Intel 5000 chipset FB-DIMM AMB temperature sensor"); | 615 | MODULE_DESCRIPTION("Intel 5000 chipset FB-DIMM AMB temperature sensor"); |
617 | MODULE_LICENSE("GPL"); | 616 | MODULE_LICENSE("GPL"); |
618 | 617 | ||
619 | module_init(i5k_amb_init); | 618 | module_init(i5k_amb_init); |
620 | module_exit(i5k_amb_exit); | 619 | module_exit(i5k_amb_exit); |
621 | 620 |
drivers/hwmon/k8temp.c
1 | /* | 1 | /* |
2 | * k8temp.c - Linux kernel module for hardware monitoring | 2 | * k8temp.c - Linux kernel module for hardware monitoring |
3 | * | 3 | * |
4 | * Copyright (C) 2006 Rudolf Marek <r.marek@assembler.cz> | 4 | * Copyright (C) 2006 Rudolf Marek <r.marek@assembler.cz> |
5 | * | 5 | * |
6 | * Inspired from the w83785 and amd756 drivers. | 6 | * Inspired from the w83785 and amd756 drivers. |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by | 9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or | 10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. | 11 | * (at your option) any later version. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
21 | * 02110-1301 USA. | 21 | * 02110-1301 USA. |
22 | */ | 22 | */ |
23 | 23 | ||
24 | #include <linux/module.h> | 24 | #include <linux/module.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/init.h> | 25 | #include <linux/init.h> |
27 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
28 | #include <linux/jiffies.h> | 27 | #include <linux/jiffies.h> |
29 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
30 | #include <linux/hwmon.h> | 29 | #include <linux/hwmon.h> |
31 | #include <linux/hwmon-sysfs.h> | 30 | #include <linux/hwmon-sysfs.h> |
32 | #include <linux/err.h> | 31 | #include <linux/err.h> |
33 | #include <linux/mutex.h> | 32 | #include <linux/mutex.h> |
34 | #include <asm/processor.h> | 33 | #include <asm/processor.h> |
35 | 34 | ||
36 | #define TEMP_FROM_REG(val) (((((val) >> 16) & 0xff) - 49) * 1000) | 35 | #define TEMP_FROM_REG(val) (((((val) >> 16) & 0xff) - 49) * 1000) |
37 | #define REG_TEMP 0xe4 | 36 | #define REG_TEMP 0xe4 |
38 | #define SEL_PLACE 0x40 | 37 | #define SEL_PLACE 0x40 |
39 | #define SEL_CORE 0x04 | 38 | #define SEL_CORE 0x04 |
40 | 39 | ||
41 | struct k8temp_data { | 40 | struct k8temp_data { |
42 | struct device *hwmon_dev; | 41 | struct device *hwmon_dev; |
43 | struct mutex update_lock; | 42 | struct mutex update_lock; |
44 | const char *name; | 43 | const char *name; |
45 | char valid; /* zero until following fields are valid */ | 44 | char valid; /* zero until following fields are valid */ |
46 | unsigned long last_updated; /* in jiffies */ | 45 | unsigned long last_updated; /* in jiffies */ |
47 | 46 | ||
48 | /* registers values */ | 47 | /* registers values */ |
49 | u8 sensorsp; /* sensor presence bits - SEL_CORE, SEL_PLACE */ | 48 | u8 sensorsp; /* sensor presence bits - SEL_CORE, SEL_PLACE */ |
50 | u32 temp[2][2]; /* core, place */ | 49 | u32 temp[2][2]; /* core, place */ |
51 | u8 swap_core_select; /* meaning of SEL_CORE is inverted */ | 50 | u8 swap_core_select; /* meaning of SEL_CORE is inverted */ |
52 | u32 temp_offset; | 51 | u32 temp_offset; |
53 | }; | 52 | }; |
54 | 53 | ||
55 | static struct k8temp_data *k8temp_update_device(struct device *dev) | 54 | static struct k8temp_data *k8temp_update_device(struct device *dev) |
56 | { | 55 | { |
57 | struct k8temp_data *data = dev_get_drvdata(dev); | 56 | struct k8temp_data *data = dev_get_drvdata(dev); |
58 | struct pci_dev *pdev = to_pci_dev(dev); | 57 | struct pci_dev *pdev = to_pci_dev(dev); |
59 | u8 tmp; | 58 | u8 tmp; |
60 | 59 | ||
61 | mutex_lock(&data->update_lock); | 60 | mutex_lock(&data->update_lock); |
62 | 61 | ||
63 | if (!data->valid | 62 | if (!data->valid |
64 | || time_after(jiffies, data->last_updated + HZ)) { | 63 | || time_after(jiffies, data->last_updated + HZ)) { |
65 | pci_read_config_byte(pdev, REG_TEMP, &tmp); | 64 | pci_read_config_byte(pdev, REG_TEMP, &tmp); |
66 | tmp &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ | 65 | tmp &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ |
67 | pci_write_config_byte(pdev, REG_TEMP, tmp); | 66 | pci_write_config_byte(pdev, REG_TEMP, tmp); |
68 | pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]); | 67 | pci_read_config_dword(pdev, REG_TEMP, &data->temp[0][0]); |
69 | 68 | ||
70 | if (data->sensorsp & SEL_PLACE) { | 69 | if (data->sensorsp & SEL_PLACE) { |
71 | tmp |= SEL_PLACE; /* Select sensor 1, core0 */ | 70 | tmp |= SEL_PLACE; /* Select sensor 1, core0 */ |
72 | pci_write_config_byte(pdev, REG_TEMP, tmp); | 71 | pci_write_config_byte(pdev, REG_TEMP, tmp); |
73 | pci_read_config_dword(pdev, REG_TEMP, | 72 | pci_read_config_dword(pdev, REG_TEMP, |
74 | &data->temp[0][1]); | 73 | &data->temp[0][1]); |
75 | } | 74 | } |
76 | 75 | ||
77 | if (data->sensorsp & SEL_CORE) { | 76 | if (data->sensorsp & SEL_CORE) { |
78 | tmp &= ~SEL_PLACE; /* Select sensor 0, core1 */ | 77 | tmp &= ~SEL_PLACE; /* Select sensor 0, core1 */ |
79 | tmp |= SEL_CORE; | 78 | tmp |= SEL_CORE; |
80 | pci_write_config_byte(pdev, REG_TEMP, tmp); | 79 | pci_write_config_byte(pdev, REG_TEMP, tmp); |
81 | pci_read_config_dword(pdev, REG_TEMP, | 80 | pci_read_config_dword(pdev, REG_TEMP, |
82 | &data->temp[1][0]); | 81 | &data->temp[1][0]); |
83 | 82 | ||
84 | if (data->sensorsp & SEL_PLACE) { | 83 | if (data->sensorsp & SEL_PLACE) { |
85 | tmp |= SEL_PLACE; /* Select sensor 1, core1 */ | 84 | tmp |= SEL_PLACE; /* Select sensor 1, core1 */ |
86 | pci_write_config_byte(pdev, REG_TEMP, tmp); | 85 | pci_write_config_byte(pdev, REG_TEMP, tmp); |
87 | pci_read_config_dword(pdev, REG_TEMP, | 86 | pci_read_config_dword(pdev, REG_TEMP, |
88 | &data->temp[1][1]); | 87 | &data->temp[1][1]); |
89 | } | 88 | } |
90 | } | 89 | } |
91 | 90 | ||
92 | data->last_updated = jiffies; | 91 | data->last_updated = jiffies; |
93 | data->valid = 1; | 92 | data->valid = 1; |
94 | } | 93 | } |
95 | 94 | ||
96 | mutex_unlock(&data->update_lock); | 95 | mutex_unlock(&data->update_lock); |
97 | return data; | 96 | return data; |
98 | } | 97 | } |
99 | 98 | ||
100 | /* | 99 | /* |
101 | * Sysfs stuff | 100 | * Sysfs stuff |
102 | */ | 101 | */ |
103 | 102 | ||
104 | static ssize_t show_name(struct device *dev, struct device_attribute | 103 | static ssize_t show_name(struct device *dev, struct device_attribute |
105 | *devattr, char *buf) | 104 | *devattr, char *buf) |
106 | { | 105 | { |
107 | struct k8temp_data *data = dev_get_drvdata(dev); | 106 | struct k8temp_data *data = dev_get_drvdata(dev); |
108 | 107 | ||
109 | return sprintf(buf, "%s\n", data->name); | 108 | return sprintf(buf, "%s\n", data->name); |
110 | } | 109 | } |
111 | 110 | ||
112 | 111 | ||
113 | static ssize_t show_temp(struct device *dev, | 112 | static ssize_t show_temp(struct device *dev, |
114 | struct device_attribute *devattr, char *buf) | 113 | struct device_attribute *devattr, char *buf) |
115 | { | 114 | { |
116 | struct sensor_device_attribute_2 *attr = | 115 | struct sensor_device_attribute_2 *attr = |
117 | to_sensor_dev_attr_2(devattr); | 116 | to_sensor_dev_attr_2(devattr); |
118 | int core = attr->nr; | 117 | int core = attr->nr; |
119 | int place = attr->index; | 118 | int place = attr->index; |
120 | int temp; | 119 | int temp; |
121 | struct k8temp_data *data = k8temp_update_device(dev); | 120 | struct k8temp_data *data = k8temp_update_device(dev); |
122 | 121 | ||
123 | if (data->swap_core_select && (data->sensorsp & SEL_CORE)) | 122 | if (data->swap_core_select && (data->sensorsp & SEL_CORE)) |
124 | core = core ? 0 : 1; | 123 | core = core ? 0 : 1; |
125 | 124 | ||
126 | temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; | 125 | temp = TEMP_FROM_REG(data->temp[core][place]) + data->temp_offset; |
127 | 126 | ||
128 | return sprintf(buf, "%d\n", temp); | 127 | return sprintf(buf, "%d\n", temp); |
129 | } | 128 | } |
130 | 129 | ||
131 | /* core, place */ | 130 | /* core, place */ |
132 | 131 | ||
133 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); | 132 | static SENSOR_DEVICE_ATTR_2(temp1_input, S_IRUGO, show_temp, NULL, 0, 0); |
134 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); | 133 | static SENSOR_DEVICE_ATTR_2(temp2_input, S_IRUGO, show_temp, NULL, 0, 1); |
135 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0); | 134 | static SENSOR_DEVICE_ATTR_2(temp3_input, S_IRUGO, show_temp, NULL, 1, 0); |
136 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1); | 135 | static SENSOR_DEVICE_ATTR_2(temp4_input, S_IRUGO, show_temp, NULL, 1, 1); |
137 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | 136 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); |
138 | 137 | ||
139 | static DEFINE_PCI_DEVICE_TABLE(k8temp_ids) = { | 138 | static DEFINE_PCI_DEVICE_TABLE(k8temp_ids) = { |
140 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, | 139 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_K8_NB_MISC) }, |
141 | { 0 }, | 140 | { 0 }, |
142 | }; | 141 | }; |
143 | 142 | ||
144 | MODULE_DEVICE_TABLE(pci, k8temp_ids); | 143 | MODULE_DEVICE_TABLE(pci, k8temp_ids); |
145 | 144 | ||
146 | static int __devinit is_rev_g_desktop(u8 model) | 145 | static int __devinit is_rev_g_desktop(u8 model) |
147 | { | 146 | { |
148 | u32 brandidx; | 147 | u32 brandidx; |
149 | 148 | ||
150 | if (model < 0x69) | 149 | if (model < 0x69) |
151 | return 0; | 150 | return 0; |
152 | 151 | ||
153 | if (model == 0xc1 || model == 0x6c || model == 0x7c) | 152 | if (model == 0xc1 || model == 0x6c || model == 0x7c) |
154 | return 0; | 153 | return 0; |
155 | 154 | ||
156 | /* | 155 | /* |
157 | * Differentiate between AM2 and ASB1. | 156 | * Differentiate between AM2 and ASB1. |
158 | * See "Constructing the processor Name String" in "Revision | 157 | * See "Constructing the processor Name String" in "Revision |
159 | * Guide for AMD NPT Family 0Fh Processors" (33610). | 158 | * Guide for AMD NPT Family 0Fh Processors" (33610). |
160 | */ | 159 | */ |
161 | brandidx = cpuid_ebx(0x80000001); | 160 | brandidx = cpuid_ebx(0x80000001); |
162 | brandidx = (brandidx >> 9) & 0x1f; | 161 | brandidx = (brandidx >> 9) & 0x1f; |
163 | 162 | ||
164 | /* Single core */ | 163 | /* Single core */ |
165 | if ((model == 0x6f || model == 0x7f) && | 164 | if ((model == 0x6f || model == 0x7f) && |
166 | (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc)) | 165 | (brandidx == 0x7 || brandidx == 0x9 || brandidx == 0xc)) |
167 | return 0; | 166 | return 0; |
168 | 167 | ||
169 | /* Dual core */ | 168 | /* Dual core */ |
170 | if (model == 0x6b && | 169 | if (model == 0x6b && |
171 | (brandidx == 0xb || brandidx == 0xc)) | 170 | (brandidx == 0xb || brandidx == 0xc)) |
172 | return 0; | 171 | return 0; |
173 | 172 | ||
174 | return 1; | 173 | return 1; |
175 | } | 174 | } |
176 | 175 | ||
177 | static int __devinit k8temp_probe(struct pci_dev *pdev, | 176 | static int __devinit k8temp_probe(struct pci_dev *pdev, |
178 | const struct pci_device_id *id) | 177 | const struct pci_device_id *id) |
179 | { | 178 | { |
180 | int err; | 179 | int err; |
181 | u8 scfg; | 180 | u8 scfg; |
182 | u32 temp; | 181 | u32 temp; |
183 | u8 model, stepping; | 182 | u8 model, stepping; |
184 | struct k8temp_data *data; | 183 | struct k8temp_data *data; |
185 | 184 | ||
186 | data = devm_kzalloc(&pdev->dev, sizeof(struct k8temp_data), GFP_KERNEL); | 185 | data = devm_kzalloc(&pdev->dev, sizeof(struct k8temp_data), GFP_KERNEL); |
187 | if (!data) | 186 | if (!data) |
188 | return -ENOMEM; | 187 | return -ENOMEM; |
189 | 188 | ||
190 | model = boot_cpu_data.x86_model; | 189 | model = boot_cpu_data.x86_model; |
191 | stepping = boot_cpu_data.x86_mask; | 190 | stepping = boot_cpu_data.x86_mask; |
192 | 191 | ||
193 | /* feature available since SH-C0, exclude older revisions */ | 192 | /* feature available since SH-C0, exclude older revisions */ |
194 | if ((model == 4 && stepping == 0) || | 193 | if ((model == 4 && stepping == 0) || |
195 | (model == 5 && stepping <= 1)) | 194 | (model == 5 && stepping <= 1)) |
196 | return -ENODEV; | 195 | return -ENODEV; |
197 | 196 | ||
198 | /* | 197 | /* |
199 | * AMD NPT family 0fh, i.e. RevF and RevG: | 198 | * AMD NPT family 0fh, i.e. RevF and RevG: |
200 | * meaning of SEL_CORE bit is inverted | 199 | * meaning of SEL_CORE bit is inverted |
201 | */ | 200 | */ |
202 | if (model >= 0x40) { | 201 | if (model >= 0x40) { |
203 | data->swap_core_select = 1; | 202 | data->swap_core_select = 1; |
204 | dev_warn(&pdev->dev, "Temperature readouts might be wrong - " | 203 | dev_warn(&pdev->dev, "Temperature readouts might be wrong - " |
205 | "check erratum #141\n"); | 204 | "check erratum #141\n"); |
206 | } | 205 | } |
207 | 206 | ||
208 | /* | 207 | /* |
209 | * RevG desktop CPUs (i.e. no socket S1G1 or ASB1 parts) need | 208 | * RevG desktop CPUs (i.e. no socket S1G1 or ASB1 parts) need |
210 | * additional offset, otherwise reported temperature is below | 209 | * additional offset, otherwise reported temperature is below |
211 | * ambient temperature | 210 | * ambient temperature |
212 | */ | 211 | */ |
213 | if (is_rev_g_desktop(model)) | 212 | if (is_rev_g_desktop(model)) |
214 | data->temp_offset = 21000; | 213 | data->temp_offset = 21000; |
215 | 214 | ||
216 | pci_read_config_byte(pdev, REG_TEMP, &scfg); | 215 | pci_read_config_byte(pdev, REG_TEMP, &scfg); |
217 | scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ | 216 | scfg &= ~(SEL_PLACE | SEL_CORE); /* Select sensor 0, core0 */ |
218 | pci_write_config_byte(pdev, REG_TEMP, scfg); | 217 | pci_write_config_byte(pdev, REG_TEMP, scfg); |
219 | pci_read_config_byte(pdev, REG_TEMP, &scfg); | 218 | pci_read_config_byte(pdev, REG_TEMP, &scfg); |
220 | 219 | ||
221 | if (scfg & (SEL_PLACE | SEL_CORE)) { | 220 | if (scfg & (SEL_PLACE | SEL_CORE)) { |
222 | dev_err(&pdev->dev, "Configuration bit(s) stuck at 1!\n"); | 221 | dev_err(&pdev->dev, "Configuration bit(s) stuck at 1!\n"); |
223 | return -ENODEV; | 222 | return -ENODEV; |
224 | } | 223 | } |
225 | 224 | ||
226 | scfg |= (SEL_PLACE | SEL_CORE); | 225 | scfg |= (SEL_PLACE | SEL_CORE); |
227 | pci_write_config_byte(pdev, REG_TEMP, scfg); | 226 | pci_write_config_byte(pdev, REG_TEMP, scfg); |
228 | 227 | ||
229 | /* now we know if we can change core and/or sensor */ | 228 | /* now we know if we can change core and/or sensor */ |
230 | pci_read_config_byte(pdev, REG_TEMP, &data->sensorsp); | 229 | pci_read_config_byte(pdev, REG_TEMP, &data->sensorsp); |
231 | 230 | ||
232 | if (data->sensorsp & SEL_PLACE) { | 231 | if (data->sensorsp & SEL_PLACE) { |
233 | scfg &= ~SEL_CORE; /* Select sensor 1, core0 */ | 232 | scfg &= ~SEL_CORE; /* Select sensor 1, core0 */ |
234 | pci_write_config_byte(pdev, REG_TEMP, scfg); | 233 | pci_write_config_byte(pdev, REG_TEMP, scfg); |
235 | pci_read_config_dword(pdev, REG_TEMP, &temp); | 234 | pci_read_config_dword(pdev, REG_TEMP, &temp); |
236 | scfg |= SEL_CORE; /* prepare for next selection */ | 235 | scfg |= SEL_CORE; /* prepare for next selection */ |
237 | if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */ | 236 | if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */ |
238 | data->sensorsp &= ~SEL_PLACE; | 237 | data->sensorsp &= ~SEL_PLACE; |
239 | } | 238 | } |
240 | 239 | ||
241 | if (data->sensorsp & SEL_CORE) { | 240 | if (data->sensorsp & SEL_CORE) { |
242 | scfg &= ~SEL_PLACE; /* Select sensor 0, core1 */ | 241 | scfg &= ~SEL_PLACE; /* Select sensor 0, core1 */ |
243 | pci_write_config_byte(pdev, REG_TEMP, scfg); | 242 | pci_write_config_byte(pdev, REG_TEMP, scfg); |
244 | pci_read_config_dword(pdev, REG_TEMP, &temp); | 243 | pci_read_config_dword(pdev, REG_TEMP, &temp); |
245 | if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */ | 244 | if (!((temp >> 16) & 0xff)) /* if temp is 0 -49C is unlikely */ |
246 | data->sensorsp &= ~SEL_CORE; | 245 | data->sensorsp &= ~SEL_CORE; |
247 | } | 246 | } |
248 | 247 | ||
249 | data->name = "k8temp"; | 248 | data->name = "k8temp"; |
250 | mutex_init(&data->update_lock); | 249 | mutex_init(&data->update_lock); |
251 | pci_set_drvdata(pdev, data); | 250 | pci_set_drvdata(pdev, data); |
252 | 251 | ||
253 | /* Register sysfs hooks */ | 252 | /* Register sysfs hooks */ |
254 | err = device_create_file(&pdev->dev, | 253 | err = device_create_file(&pdev->dev, |
255 | &sensor_dev_attr_temp1_input.dev_attr); | 254 | &sensor_dev_attr_temp1_input.dev_attr); |
256 | if (err) | 255 | if (err) |
257 | goto exit_remove; | 256 | goto exit_remove; |
258 | 257 | ||
259 | /* sensor can be changed and reports something */ | 258 | /* sensor can be changed and reports something */ |
260 | if (data->sensorsp & SEL_PLACE) { | 259 | if (data->sensorsp & SEL_PLACE) { |
261 | err = device_create_file(&pdev->dev, | 260 | err = device_create_file(&pdev->dev, |
262 | &sensor_dev_attr_temp2_input.dev_attr); | 261 | &sensor_dev_attr_temp2_input.dev_attr); |
263 | if (err) | 262 | if (err) |
264 | goto exit_remove; | 263 | goto exit_remove; |
265 | } | 264 | } |
266 | 265 | ||
267 | /* core can be changed and reports something */ | 266 | /* core can be changed and reports something */ |
268 | if (data->sensorsp & SEL_CORE) { | 267 | if (data->sensorsp & SEL_CORE) { |
269 | err = device_create_file(&pdev->dev, | 268 | err = device_create_file(&pdev->dev, |
270 | &sensor_dev_attr_temp3_input.dev_attr); | 269 | &sensor_dev_attr_temp3_input.dev_attr); |
271 | if (err) | 270 | if (err) |
272 | goto exit_remove; | 271 | goto exit_remove; |
273 | if (data->sensorsp & SEL_PLACE) { | 272 | if (data->sensorsp & SEL_PLACE) { |
274 | err = device_create_file(&pdev->dev, | 273 | err = device_create_file(&pdev->dev, |
275 | &sensor_dev_attr_temp4_input. | 274 | &sensor_dev_attr_temp4_input. |
276 | dev_attr); | 275 | dev_attr); |
277 | if (err) | 276 | if (err) |
278 | goto exit_remove; | 277 | goto exit_remove; |
279 | } | 278 | } |
280 | } | 279 | } |
281 | 280 | ||
282 | err = device_create_file(&pdev->dev, &dev_attr_name); | 281 | err = device_create_file(&pdev->dev, &dev_attr_name); |
283 | if (err) | 282 | if (err) |
284 | goto exit_remove; | 283 | goto exit_remove; |
285 | 284 | ||
286 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | 285 | data->hwmon_dev = hwmon_device_register(&pdev->dev); |
287 | 286 | ||
288 | if (IS_ERR(data->hwmon_dev)) { | 287 | if (IS_ERR(data->hwmon_dev)) { |
289 | err = PTR_ERR(data->hwmon_dev); | 288 | err = PTR_ERR(data->hwmon_dev); |
290 | goto exit_remove; | 289 | goto exit_remove; |
291 | } | 290 | } |
292 | 291 | ||
293 | return 0; | 292 | return 0; |
294 | 293 | ||
295 | exit_remove: | 294 | exit_remove: |
296 | device_remove_file(&pdev->dev, | 295 | device_remove_file(&pdev->dev, |
297 | &sensor_dev_attr_temp1_input.dev_attr); | 296 | &sensor_dev_attr_temp1_input.dev_attr); |
298 | device_remove_file(&pdev->dev, | 297 | device_remove_file(&pdev->dev, |
299 | &sensor_dev_attr_temp2_input.dev_attr); | 298 | &sensor_dev_attr_temp2_input.dev_attr); |
300 | device_remove_file(&pdev->dev, | 299 | device_remove_file(&pdev->dev, |
301 | &sensor_dev_attr_temp3_input.dev_attr); | 300 | &sensor_dev_attr_temp3_input.dev_attr); |
302 | device_remove_file(&pdev->dev, | 301 | device_remove_file(&pdev->dev, |
303 | &sensor_dev_attr_temp4_input.dev_attr); | 302 | &sensor_dev_attr_temp4_input.dev_attr); |
304 | device_remove_file(&pdev->dev, &dev_attr_name); | 303 | device_remove_file(&pdev->dev, &dev_attr_name); |
305 | return err; | 304 | return err; |
306 | } | 305 | } |
307 | 306 | ||
308 | static void __devexit k8temp_remove(struct pci_dev *pdev) | 307 | static void __devexit k8temp_remove(struct pci_dev *pdev) |
309 | { | 308 | { |
310 | struct k8temp_data *data = pci_get_drvdata(pdev); | 309 | struct k8temp_data *data = pci_get_drvdata(pdev); |
311 | 310 | ||
312 | hwmon_device_unregister(data->hwmon_dev); | 311 | hwmon_device_unregister(data->hwmon_dev); |
313 | device_remove_file(&pdev->dev, | 312 | device_remove_file(&pdev->dev, |
314 | &sensor_dev_attr_temp1_input.dev_attr); | 313 | &sensor_dev_attr_temp1_input.dev_attr); |
315 | device_remove_file(&pdev->dev, | 314 | device_remove_file(&pdev->dev, |
316 | &sensor_dev_attr_temp2_input.dev_attr); | 315 | &sensor_dev_attr_temp2_input.dev_attr); |
317 | device_remove_file(&pdev->dev, | 316 | device_remove_file(&pdev->dev, |
318 | &sensor_dev_attr_temp3_input.dev_attr); | 317 | &sensor_dev_attr_temp3_input.dev_attr); |
319 | device_remove_file(&pdev->dev, | 318 | device_remove_file(&pdev->dev, |
320 | &sensor_dev_attr_temp4_input.dev_attr); | 319 | &sensor_dev_attr_temp4_input.dev_attr); |
321 | device_remove_file(&pdev->dev, &dev_attr_name); | 320 | device_remove_file(&pdev->dev, &dev_attr_name); |
322 | } | 321 | } |
323 | 322 | ||
324 | static struct pci_driver k8temp_driver = { | 323 | static struct pci_driver k8temp_driver = { |
325 | .name = "k8temp", | 324 | .name = "k8temp", |
326 | .id_table = k8temp_ids, | 325 | .id_table = k8temp_ids, |
327 | .probe = k8temp_probe, | 326 | .probe = k8temp_probe, |
328 | .remove = __devexit_p(k8temp_remove), | 327 | .remove = __devexit_p(k8temp_remove), |
329 | }; | 328 | }; |
330 | 329 | ||
331 | module_pci_driver(k8temp_driver); | 330 | module_pci_driver(k8temp_driver); |
332 | 331 | ||
333 | MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); | 332 | MODULE_AUTHOR("Rudolf Marek <r.marek@assembler.cz>"); |
334 | MODULE_DESCRIPTION("AMD K8 core temperature monitor"); | 333 | MODULE_DESCRIPTION("AMD K8 core temperature monitor"); |
335 | MODULE_LICENSE("GPL"); | 334 | MODULE_LICENSE("GPL"); |
336 | 335 |
drivers/hwmon/max16065.c
1 | /* | 1 | /* |
2 | * Driver for | 2 | * Driver for |
3 | * Maxim MAX16065/MAX16066 12-Channel/8-Channel, Flash-Configurable | 3 | * Maxim MAX16065/MAX16066 12-Channel/8-Channel, Flash-Configurable |
4 | * System Managers with Nonvolatile Fault Registers | 4 | * System Managers with Nonvolatile Fault Registers |
5 | * Maxim MAX16067/MAX16068 6-Channel, Flash-Configurable System Managers | 5 | * Maxim MAX16067/MAX16068 6-Channel, Flash-Configurable System Managers |
6 | * with Nonvolatile Fault Registers | 6 | * with Nonvolatile Fault Registers |
7 | * Maxim MAX16070/MAX16071 12-Channel/8-Channel, Flash-Configurable System | 7 | * Maxim MAX16070/MAX16071 12-Channel/8-Channel, Flash-Configurable System |
8 | * Monitors with Nonvolatile Fault Registers | 8 | * Monitors with Nonvolatile Fault Registers |
9 | * | 9 | * |
10 | * Copyright (C) 2011 Ericsson AB. | 10 | * Copyright (C) 2011 Ericsson AB. |
11 | * | 11 | * |
12 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
13 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
14 | * the Free Software Foundation; version 2 of the License. | 14 | * the Free Software Foundation; version 2 of the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | #include <linux/kernel.h> | 17 | #include <linux/kernel.h> |
18 | #include <linux/module.h> | 18 | #include <linux/module.h> |
19 | #include <linux/init.h> | 19 | #include <linux/init.h> |
20 | #include <linux/err.h> | 20 | #include <linux/err.h> |
21 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
23 | #include <linux/hwmon.h> | 23 | #include <linux/hwmon.h> |
24 | #include <linux/hwmon-sysfs.h> | 24 | #include <linux/hwmon-sysfs.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/jiffies.h> | 25 | #include <linux/jiffies.h> |
27 | 26 | ||
28 | enum chips { max16065, max16066, max16067, max16068, max16070, max16071 }; | 27 | enum chips { max16065, max16066, max16067, max16068, max16070, max16071 }; |
29 | 28 | ||
30 | /* | 29 | /* |
31 | * Registers | 30 | * Registers |
32 | */ | 31 | */ |
33 | #define MAX16065_ADC(x) ((x) * 2) | 32 | #define MAX16065_ADC(x) ((x) * 2) |
34 | 33 | ||
35 | #define MAX16065_CURR_SENSE 0x18 | 34 | #define MAX16065_CURR_SENSE 0x18 |
36 | #define MAX16065_CSP_ADC 0x19 | 35 | #define MAX16065_CSP_ADC 0x19 |
37 | #define MAX16065_FAULT(x) (0x1b + (x)) | 36 | #define MAX16065_FAULT(x) (0x1b + (x)) |
38 | #define MAX16065_SCALE(x) (0x43 + (x)) | 37 | #define MAX16065_SCALE(x) (0x43 + (x)) |
39 | #define MAX16065_CURR_CONTROL 0x47 | 38 | #define MAX16065_CURR_CONTROL 0x47 |
40 | #define MAX16065_LIMIT(l, x) (0x48 + (l) + (x) * 3) /* | 39 | #define MAX16065_LIMIT(l, x) (0x48 + (l) + (x) * 3) /* |
41 | * l: limit | 40 | * l: limit |
42 | * 0: min/max | 41 | * 0: min/max |
43 | * 1: crit | 42 | * 1: crit |
44 | * 2: lcrit | 43 | * 2: lcrit |
45 | * x: ADC index | 44 | * x: ADC index |
46 | */ | 45 | */ |
47 | 46 | ||
48 | #define MAX16065_SW_ENABLE 0x73 | 47 | #define MAX16065_SW_ENABLE 0x73 |
49 | 48 | ||
50 | #define MAX16065_WARNING_OV (1 << 3) /* Set if secondary threshold is OV | 49 | #define MAX16065_WARNING_OV (1 << 3) /* Set if secondary threshold is OV |
51 | warning */ | 50 | warning */ |
52 | 51 | ||
53 | #define MAX16065_CURR_ENABLE (1 << 0) | 52 | #define MAX16065_CURR_ENABLE (1 << 0) |
54 | 53 | ||
55 | #define MAX16065_NUM_LIMIT 3 | 54 | #define MAX16065_NUM_LIMIT 3 |
56 | #define MAX16065_NUM_ADC 12 /* maximum number of ADC channels */ | 55 | #define MAX16065_NUM_ADC 12 /* maximum number of ADC channels */ |
57 | 56 | ||
58 | static const int max16065_num_adc[] = { | 57 | static const int max16065_num_adc[] = { |
59 | [max16065] = 12, | 58 | [max16065] = 12, |
60 | [max16066] = 8, | 59 | [max16066] = 8, |
61 | [max16067] = 6, | 60 | [max16067] = 6, |
62 | [max16068] = 6, | 61 | [max16068] = 6, |
63 | [max16070] = 12, | 62 | [max16070] = 12, |
64 | [max16071] = 8, | 63 | [max16071] = 8, |
65 | }; | 64 | }; |
66 | 65 | ||
67 | static const bool max16065_have_secondary[] = { | 66 | static const bool max16065_have_secondary[] = { |
68 | [max16065] = true, | 67 | [max16065] = true, |
69 | [max16066] = true, | 68 | [max16066] = true, |
70 | [max16067] = false, | 69 | [max16067] = false, |
71 | [max16068] = false, | 70 | [max16068] = false, |
72 | [max16070] = true, | 71 | [max16070] = true, |
73 | [max16071] = true, | 72 | [max16071] = true, |
74 | }; | 73 | }; |
75 | 74 | ||
76 | static const bool max16065_have_current[] = { | 75 | static const bool max16065_have_current[] = { |
77 | [max16065] = true, | 76 | [max16065] = true, |
78 | [max16066] = true, | 77 | [max16066] = true, |
79 | [max16067] = false, | 78 | [max16067] = false, |
80 | [max16068] = false, | 79 | [max16068] = false, |
81 | [max16070] = true, | 80 | [max16070] = true, |
82 | [max16071] = true, | 81 | [max16071] = true, |
83 | }; | 82 | }; |
84 | 83 | ||
85 | struct max16065_data { | 84 | struct max16065_data { |
86 | enum chips type; | 85 | enum chips type; |
87 | struct device *hwmon_dev; | 86 | struct device *hwmon_dev; |
88 | struct mutex update_lock; | 87 | struct mutex update_lock; |
89 | bool valid; | 88 | bool valid; |
90 | unsigned long last_updated; /* in jiffies */ | 89 | unsigned long last_updated; /* in jiffies */ |
91 | int num_adc; | 90 | int num_adc; |
92 | bool have_current; | 91 | bool have_current; |
93 | int curr_gain; | 92 | int curr_gain; |
94 | /* limits are in mV */ | 93 | /* limits are in mV */ |
95 | int limit[MAX16065_NUM_LIMIT][MAX16065_NUM_ADC]; | 94 | int limit[MAX16065_NUM_LIMIT][MAX16065_NUM_ADC]; |
96 | int range[MAX16065_NUM_ADC + 1];/* voltage range */ | 95 | int range[MAX16065_NUM_ADC + 1];/* voltage range */ |
97 | int adc[MAX16065_NUM_ADC + 1]; /* adc values (raw) including csp_adc */ | 96 | int adc[MAX16065_NUM_ADC + 1]; /* adc values (raw) including csp_adc */ |
98 | int curr_sense; | 97 | int curr_sense; |
99 | int fault[2]; | 98 | int fault[2]; |
100 | }; | 99 | }; |
101 | 100 | ||
102 | static const int max16065_adc_range[] = { 5560, 2780, 1390, 0 }; | 101 | static const int max16065_adc_range[] = { 5560, 2780, 1390, 0 }; |
103 | static const int max16065_csp_adc_range[] = { 7000, 14000 }; | 102 | static const int max16065_csp_adc_range[] = { 7000, 14000 }; |
104 | 103 | ||
105 | /* ADC registers have 10 bit resolution. */ | 104 | /* ADC registers have 10 bit resolution. */ |
106 | static inline int ADC_TO_MV(int adc, int range) | 105 | static inline int ADC_TO_MV(int adc, int range) |
107 | { | 106 | { |
108 | return (adc * range) / 1024; | 107 | return (adc * range) / 1024; |
109 | } | 108 | } |
110 | 109 | ||
111 | /* | 110 | /* |
112 | * Limit registers have 8 bit resolution and match upper 8 bits of ADC | 111 | * Limit registers have 8 bit resolution and match upper 8 bits of ADC |
113 | * registers. | 112 | * registers. |
114 | */ | 113 | */ |
115 | static inline int LIMIT_TO_MV(int limit, int range) | 114 | static inline int LIMIT_TO_MV(int limit, int range) |
116 | { | 115 | { |
117 | return limit * range / 256; | 116 | return limit * range / 256; |
118 | } | 117 | } |
119 | 118 | ||
120 | static inline int MV_TO_LIMIT(int mv, int range) | 119 | static inline int MV_TO_LIMIT(int mv, int range) |
121 | { | 120 | { |
122 | return SENSORS_LIMIT(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255); | 121 | return SENSORS_LIMIT(DIV_ROUND_CLOSEST(mv * 256, range), 0, 255); |
123 | } | 122 | } |
124 | 123 | ||
125 | static inline int ADC_TO_CURR(int adc, int gain) | 124 | static inline int ADC_TO_CURR(int adc, int gain) |
126 | { | 125 | { |
127 | return adc * 1400000 / (gain * 255); | 126 | return adc * 1400000 / (gain * 255); |
128 | } | 127 | } |
129 | 128 | ||
130 | /* | 129 | /* |
131 | * max16065_read_adc() | 130 | * max16065_read_adc() |
132 | * | 131 | * |
133 | * Read 16 bit value from <reg>, <reg+1>. | 132 | * Read 16 bit value from <reg>, <reg+1>. |
134 | * Upper 8 bits are in <reg>, lower 2 bits are in bits 7:6 of <reg+1>. | 133 | * Upper 8 bits are in <reg>, lower 2 bits are in bits 7:6 of <reg+1>. |
135 | */ | 134 | */ |
136 | static int max16065_read_adc(struct i2c_client *client, int reg) | 135 | static int max16065_read_adc(struct i2c_client *client, int reg) |
137 | { | 136 | { |
138 | int rv; | 137 | int rv; |
139 | 138 | ||
140 | rv = i2c_smbus_read_word_swapped(client, reg); | 139 | rv = i2c_smbus_read_word_swapped(client, reg); |
141 | if (unlikely(rv < 0)) | 140 | if (unlikely(rv < 0)) |
142 | return rv; | 141 | return rv; |
143 | return rv >> 6; | 142 | return rv >> 6; |
144 | } | 143 | } |
145 | 144 | ||
146 | static struct max16065_data *max16065_update_device(struct device *dev) | 145 | static struct max16065_data *max16065_update_device(struct device *dev) |
147 | { | 146 | { |
148 | struct i2c_client *client = to_i2c_client(dev); | 147 | struct i2c_client *client = to_i2c_client(dev); |
149 | struct max16065_data *data = i2c_get_clientdata(client); | 148 | struct max16065_data *data = i2c_get_clientdata(client); |
150 | 149 | ||
151 | mutex_lock(&data->update_lock); | 150 | mutex_lock(&data->update_lock); |
152 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 151 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
153 | int i; | 152 | int i; |
154 | 153 | ||
155 | for (i = 0; i < data->num_adc; i++) | 154 | for (i = 0; i < data->num_adc; i++) |
156 | data->adc[i] | 155 | data->adc[i] |
157 | = max16065_read_adc(client, MAX16065_ADC(i)); | 156 | = max16065_read_adc(client, MAX16065_ADC(i)); |
158 | 157 | ||
159 | if (data->have_current) { | 158 | if (data->have_current) { |
160 | data->adc[MAX16065_NUM_ADC] | 159 | data->adc[MAX16065_NUM_ADC] |
161 | = max16065_read_adc(client, MAX16065_CSP_ADC); | 160 | = max16065_read_adc(client, MAX16065_CSP_ADC); |
162 | data->curr_sense | 161 | data->curr_sense |
163 | = i2c_smbus_read_byte_data(client, | 162 | = i2c_smbus_read_byte_data(client, |
164 | MAX16065_CURR_SENSE); | 163 | MAX16065_CURR_SENSE); |
165 | } | 164 | } |
166 | 165 | ||
167 | for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++) | 166 | for (i = 0; i < DIV_ROUND_UP(data->num_adc, 8); i++) |
168 | data->fault[i] | 167 | data->fault[i] |
169 | = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i)); | 168 | = i2c_smbus_read_byte_data(client, MAX16065_FAULT(i)); |
170 | 169 | ||
171 | data->last_updated = jiffies; | 170 | data->last_updated = jiffies; |
172 | data->valid = 1; | 171 | data->valid = 1; |
173 | } | 172 | } |
174 | mutex_unlock(&data->update_lock); | 173 | mutex_unlock(&data->update_lock); |
175 | return data; | 174 | return data; |
176 | } | 175 | } |
177 | 176 | ||
178 | static ssize_t max16065_show_alarm(struct device *dev, | 177 | static ssize_t max16065_show_alarm(struct device *dev, |
179 | struct device_attribute *da, char *buf) | 178 | struct device_attribute *da, char *buf) |
180 | { | 179 | { |
181 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | 180 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); |
182 | struct max16065_data *data = max16065_update_device(dev); | 181 | struct max16065_data *data = max16065_update_device(dev); |
183 | int val = data->fault[attr2->nr]; | 182 | int val = data->fault[attr2->nr]; |
184 | 183 | ||
185 | if (val < 0) | 184 | if (val < 0) |
186 | return val; | 185 | return val; |
187 | 186 | ||
188 | val &= (1 << attr2->index); | 187 | val &= (1 << attr2->index); |
189 | if (val) | 188 | if (val) |
190 | i2c_smbus_write_byte_data(to_i2c_client(dev), | 189 | i2c_smbus_write_byte_data(to_i2c_client(dev), |
191 | MAX16065_FAULT(attr2->nr), val); | 190 | MAX16065_FAULT(attr2->nr), val); |
192 | 191 | ||
193 | return snprintf(buf, PAGE_SIZE, "%d\n", !!val); | 192 | return snprintf(buf, PAGE_SIZE, "%d\n", !!val); |
194 | } | 193 | } |
195 | 194 | ||
196 | static ssize_t max16065_show_input(struct device *dev, | 195 | static ssize_t max16065_show_input(struct device *dev, |
197 | struct device_attribute *da, char *buf) | 196 | struct device_attribute *da, char *buf) |
198 | { | 197 | { |
199 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 198 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
200 | struct max16065_data *data = max16065_update_device(dev); | 199 | struct max16065_data *data = max16065_update_device(dev); |
201 | int adc = data->adc[attr->index]; | 200 | int adc = data->adc[attr->index]; |
202 | 201 | ||
203 | if (unlikely(adc < 0)) | 202 | if (unlikely(adc < 0)) |
204 | return adc; | 203 | return adc; |
205 | 204 | ||
206 | return snprintf(buf, PAGE_SIZE, "%d\n", | 205 | return snprintf(buf, PAGE_SIZE, "%d\n", |
207 | ADC_TO_MV(adc, data->range[attr->index])); | 206 | ADC_TO_MV(adc, data->range[attr->index])); |
208 | } | 207 | } |
209 | 208 | ||
210 | static ssize_t max16065_show_current(struct device *dev, | 209 | static ssize_t max16065_show_current(struct device *dev, |
211 | struct device_attribute *da, char *buf) | 210 | struct device_attribute *da, char *buf) |
212 | { | 211 | { |
213 | struct max16065_data *data = max16065_update_device(dev); | 212 | struct max16065_data *data = max16065_update_device(dev); |
214 | 213 | ||
215 | if (unlikely(data->curr_sense < 0)) | 214 | if (unlikely(data->curr_sense < 0)) |
216 | return data->curr_sense; | 215 | return data->curr_sense; |
217 | 216 | ||
218 | return snprintf(buf, PAGE_SIZE, "%d\n", | 217 | return snprintf(buf, PAGE_SIZE, "%d\n", |
219 | ADC_TO_CURR(data->curr_sense, data->curr_gain)); | 218 | ADC_TO_CURR(data->curr_sense, data->curr_gain)); |
220 | } | 219 | } |
221 | 220 | ||
222 | static ssize_t max16065_set_limit(struct device *dev, | 221 | static ssize_t max16065_set_limit(struct device *dev, |
223 | struct device_attribute *da, | 222 | struct device_attribute *da, |
224 | const char *buf, size_t count) | 223 | const char *buf, size_t count) |
225 | { | 224 | { |
226 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | 225 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); |
227 | struct i2c_client *client = to_i2c_client(dev); | 226 | struct i2c_client *client = to_i2c_client(dev); |
228 | struct max16065_data *data = i2c_get_clientdata(client); | 227 | struct max16065_data *data = i2c_get_clientdata(client); |
229 | unsigned long val; | 228 | unsigned long val; |
230 | int err; | 229 | int err; |
231 | int limit; | 230 | int limit; |
232 | 231 | ||
233 | err = kstrtoul(buf, 10, &val); | 232 | err = kstrtoul(buf, 10, &val); |
234 | if (unlikely(err < 0)) | 233 | if (unlikely(err < 0)) |
235 | return err; | 234 | return err; |
236 | 235 | ||
237 | limit = MV_TO_LIMIT(val, data->range[attr2->index]); | 236 | limit = MV_TO_LIMIT(val, data->range[attr2->index]); |
238 | 237 | ||
239 | mutex_lock(&data->update_lock); | 238 | mutex_lock(&data->update_lock); |
240 | data->limit[attr2->nr][attr2->index] | 239 | data->limit[attr2->nr][attr2->index] |
241 | = LIMIT_TO_MV(limit, data->range[attr2->index]); | 240 | = LIMIT_TO_MV(limit, data->range[attr2->index]); |
242 | i2c_smbus_write_byte_data(client, | 241 | i2c_smbus_write_byte_data(client, |
243 | MAX16065_LIMIT(attr2->nr, attr2->index), | 242 | MAX16065_LIMIT(attr2->nr, attr2->index), |
244 | limit); | 243 | limit); |
245 | mutex_unlock(&data->update_lock); | 244 | mutex_unlock(&data->update_lock); |
246 | 245 | ||
247 | return count; | 246 | return count; |
248 | } | 247 | } |
249 | 248 | ||
250 | static ssize_t max16065_show_limit(struct device *dev, | 249 | static ssize_t max16065_show_limit(struct device *dev, |
251 | struct device_attribute *da, char *buf) | 250 | struct device_attribute *da, char *buf) |
252 | { | 251 | { |
253 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); | 252 | struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(da); |
254 | struct i2c_client *client = to_i2c_client(dev); | 253 | struct i2c_client *client = to_i2c_client(dev); |
255 | struct max16065_data *data = i2c_get_clientdata(client); | 254 | struct max16065_data *data = i2c_get_clientdata(client); |
256 | 255 | ||
257 | return snprintf(buf, PAGE_SIZE, "%d\n", | 256 | return snprintf(buf, PAGE_SIZE, "%d\n", |
258 | data->limit[attr2->nr][attr2->index]); | 257 | data->limit[attr2->nr][attr2->index]); |
259 | } | 258 | } |
260 | 259 | ||
261 | /* Construct a sensor_device_attribute structure for each register */ | 260 | /* Construct a sensor_device_attribute structure for each register */ |
262 | 261 | ||
263 | /* Input voltages */ | 262 | /* Input voltages */ |
264 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, max16065_show_input, NULL, 0); | 263 | static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, max16065_show_input, NULL, 0); |
265 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, max16065_show_input, NULL, 1); | 264 | static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, max16065_show_input, NULL, 1); |
266 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, max16065_show_input, NULL, 2); | 265 | static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, max16065_show_input, NULL, 2); |
267 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, max16065_show_input, NULL, 3); | 266 | static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, max16065_show_input, NULL, 3); |
268 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, max16065_show_input, NULL, 4); | 267 | static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, max16065_show_input, NULL, 4); |
269 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, max16065_show_input, NULL, 5); | 268 | static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, max16065_show_input, NULL, 5); |
270 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, max16065_show_input, NULL, 6); | 269 | static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, max16065_show_input, NULL, 6); |
271 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, max16065_show_input, NULL, 7); | 270 | static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, max16065_show_input, NULL, 7); |
272 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, max16065_show_input, NULL, 8); | 271 | static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, max16065_show_input, NULL, 8); |
273 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, max16065_show_input, NULL, 9); | 272 | static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, max16065_show_input, NULL, 9); |
274 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, max16065_show_input, NULL, 10); | 273 | static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, max16065_show_input, NULL, 10); |
275 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, max16065_show_input, NULL, 11); | 274 | static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, max16065_show_input, NULL, 11); |
276 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, max16065_show_input, NULL, 12); | 275 | static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, max16065_show_input, NULL, 12); |
277 | 276 | ||
278 | /* Input voltages lcrit */ | 277 | /* Input voltages lcrit */ |
279 | static SENSOR_DEVICE_ATTR_2(in0_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 278 | static SENSOR_DEVICE_ATTR_2(in0_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
280 | max16065_set_limit, 2, 0); | 279 | max16065_set_limit, 2, 0); |
281 | static SENSOR_DEVICE_ATTR_2(in1_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 280 | static SENSOR_DEVICE_ATTR_2(in1_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
282 | max16065_set_limit, 2, 1); | 281 | max16065_set_limit, 2, 1); |
283 | static SENSOR_DEVICE_ATTR_2(in2_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 282 | static SENSOR_DEVICE_ATTR_2(in2_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
284 | max16065_set_limit, 2, 2); | 283 | max16065_set_limit, 2, 2); |
285 | static SENSOR_DEVICE_ATTR_2(in3_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 284 | static SENSOR_DEVICE_ATTR_2(in3_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
286 | max16065_set_limit, 2, 3); | 285 | max16065_set_limit, 2, 3); |
287 | static SENSOR_DEVICE_ATTR_2(in4_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 286 | static SENSOR_DEVICE_ATTR_2(in4_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
288 | max16065_set_limit, 2, 4); | 287 | max16065_set_limit, 2, 4); |
289 | static SENSOR_DEVICE_ATTR_2(in5_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 288 | static SENSOR_DEVICE_ATTR_2(in5_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
290 | max16065_set_limit, 2, 5); | 289 | max16065_set_limit, 2, 5); |
291 | static SENSOR_DEVICE_ATTR_2(in6_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 290 | static SENSOR_DEVICE_ATTR_2(in6_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
292 | max16065_set_limit, 2, 6); | 291 | max16065_set_limit, 2, 6); |
293 | static SENSOR_DEVICE_ATTR_2(in7_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 292 | static SENSOR_DEVICE_ATTR_2(in7_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
294 | max16065_set_limit, 2, 7); | 293 | max16065_set_limit, 2, 7); |
295 | static SENSOR_DEVICE_ATTR_2(in8_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 294 | static SENSOR_DEVICE_ATTR_2(in8_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
296 | max16065_set_limit, 2, 8); | 295 | max16065_set_limit, 2, 8); |
297 | static SENSOR_DEVICE_ATTR_2(in9_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 296 | static SENSOR_DEVICE_ATTR_2(in9_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
298 | max16065_set_limit, 2, 9); | 297 | max16065_set_limit, 2, 9); |
299 | static SENSOR_DEVICE_ATTR_2(in10_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 298 | static SENSOR_DEVICE_ATTR_2(in10_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
300 | max16065_set_limit, 2, 10); | 299 | max16065_set_limit, 2, 10); |
301 | static SENSOR_DEVICE_ATTR_2(in11_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, | 300 | static SENSOR_DEVICE_ATTR_2(in11_lcrit, S_IWUSR | S_IRUGO, max16065_show_limit, |
302 | max16065_set_limit, 2, 11); | 301 | max16065_set_limit, 2, 11); |
303 | 302 | ||
304 | /* Input voltages crit */ | 303 | /* Input voltages crit */ |
305 | static SENSOR_DEVICE_ATTR_2(in0_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 304 | static SENSOR_DEVICE_ATTR_2(in0_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
306 | max16065_set_limit, 1, 0); | 305 | max16065_set_limit, 1, 0); |
307 | static SENSOR_DEVICE_ATTR_2(in1_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 306 | static SENSOR_DEVICE_ATTR_2(in1_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
308 | max16065_set_limit, 1, 1); | 307 | max16065_set_limit, 1, 1); |
309 | static SENSOR_DEVICE_ATTR_2(in2_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 308 | static SENSOR_DEVICE_ATTR_2(in2_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
310 | max16065_set_limit, 1, 2); | 309 | max16065_set_limit, 1, 2); |
311 | static SENSOR_DEVICE_ATTR_2(in3_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 310 | static SENSOR_DEVICE_ATTR_2(in3_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
312 | max16065_set_limit, 1, 3); | 311 | max16065_set_limit, 1, 3); |
313 | static SENSOR_DEVICE_ATTR_2(in4_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 312 | static SENSOR_DEVICE_ATTR_2(in4_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
314 | max16065_set_limit, 1, 4); | 313 | max16065_set_limit, 1, 4); |
315 | static SENSOR_DEVICE_ATTR_2(in5_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 314 | static SENSOR_DEVICE_ATTR_2(in5_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
316 | max16065_set_limit, 1, 5); | 315 | max16065_set_limit, 1, 5); |
317 | static SENSOR_DEVICE_ATTR_2(in6_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 316 | static SENSOR_DEVICE_ATTR_2(in6_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
318 | max16065_set_limit, 1, 6); | 317 | max16065_set_limit, 1, 6); |
319 | static SENSOR_DEVICE_ATTR_2(in7_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 318 | static SENSOR_DEVICE_ATTR_2(in7_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
320 | max16065_set_limit, 1, 7); | 319 | max16065_set_limit, 1, 7); |
321 | static SENSOR_DEVICE_ATTR_2(in8_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 320 | static SENSOR_DEVICE_ATTR_2(in8_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
322 | max16065_set_limit, 1, 8); | 321 | max16065_set_limit, 1, 8); |
323 | static SENSOR_DEVICE_ATTR_2(in9_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 322 | static SENSOR_DEVICE_ATTR_2(in9_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
324 | max16065_set_limit, 1, 9); | 323 | max16065_set_limit, 1, 9); |
325 | static SENSOR_DEVICE_ATTR_2(in10_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 324 | static SENSOR_DEVICE_ATTR_2(in10_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
326 | max16065_set_limit, 1, 10); | 325 | max16065_set_limit, 1, 10); |
327 | static SENSOR_DEVICE_ATTR_2(in11_crit, S_IWUSR | S_IRUGO, max16065_show_limit, | 326 | static SENSOR_DEVICE_ATTR_2(in11_crit, S_IWUSR | S_IRUGO, max16065_show_limit, |
328 | max16065_set_limit, 1, 11); | 327 | max16065_set_limit, 1, 11); |
329 | 328 | ||
330 | /* Input voltages min */ | 329 | /* Input voltages min */ |
331 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 330 | static SENSOR_DEVICE_ATTR_2(in0_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
332 | max16065_set_limit, 0, 0); | 331 | max16065_set_limit, 0, 0); |
333 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 332 | static SENSOR_DEVICE_ATTR_2(in1_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
334 | max16065_set_limit, 0, 1); | 333 | max16065_set_limit, 0, 1); |
335 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 334 | static SENSOR_DEVICE_ATTR_2(in2_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
336 | max16065_set_limit, 0, 2); | 335 | max16065_set_limit, 0, 2); |
337 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 336 | static SENSOR_DEVICE_ATTR_2(in3_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
338 | max16065_set_limit, 0, 3); | 337 | max16065_set_limit, 0, 3); |
339 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 338 | static SENSOR_DEVICE_ATTR_2(in4_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
340 | max16065_set_limit, 0, 4); | 339 | max16065_set_limit, 0, 4); |
341 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 340 | static SENSOR_DEVICE_ATTR_2(in5_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
342 | max16065_set_limit, 0, 5); | 341 | max16065_set_limit, 0, 5); |
343 | static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 342 | static SENSOR_DEVICE_ATTR_2(in6_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
344 | max16065_set_limit, 0, 6); | 343 | max16065_set_limit, 0, 6); |
345 | static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 344 | static SENSOR_DEVICE_ATTR_2(in7_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
346 | max16065_set_limit, 0, 7); | 345 | max16065_set_limit, 0, 7); |
347 | static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 346 | static SENSOR_DEVICE_ATTR_2(in8_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
348 | max16065_set_limit, 0, 8); | 347 | max16065_set_limit, 0, 8); |
349 | static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 348 | static SENSOR_DEVICE_ATTR_2(in9_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
350 | max16065_set_limit, 0, 9); | 349 | max16065_set_limit, 0, 9); |
351 | static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 350 | static SENSOR_DEVICE_ATTR_2(in10_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
352 | max16065_set_limit, 0, 10); | 351 | max16065_set_limit, 0, 10); |
353 | static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, max16065_show_limit, | 352 | static SENSOR_DEVICE_ATTR_2(in11_min, S_IWUSR | S_IRUGO, max16065_show_limit, |
354 | max16065_set_limit, 0, 11); | 353 | max16065_set_limit, 0, 11); |
355 | 354 | ||
356 | /* Input voltages max */ | 355 | /* Input voltages max */ |
357 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 356 | static SENSOR_DEVICE_ATTR_2(in0_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
358 | max16065_set_limit, 0, 0); | 357 | max16065_set_limit, 0, 0); |
359 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 358 | static SENSOR_DEVICE_ATTR_2(in1_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
360 | max16065_set_limit, 0, 1); | 359 | max16065_set_limit, 0, 1); |
361 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 360 | static SENSOR_DEVICE_ATTR_2(in2_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
362 | max16065_set_limit, 0, 2); | 361 | max16065_set_limit, 0, 2); |
363 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 362 | static SENSOR_DEVICE_ATTR_2(in3_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
364 | max16065_set_limit, 0, 3); | 363 | max16065_set_limit, 0, 3); |
365 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 364 | static SENSOR_DEVICE_ATTR_2(in4_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
366 | max16065_set_limit, 0, 4); | 365 | max16065_set_limit, 0, 4); |
367 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 366 | static SENSOR_DEVICE_ATTR_2(in5_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
368 | max16065_set_limit, 0, 5); | 367 | max16065_set_limit, 0, 5); |
369 | static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 368 | static SENSOR_DEVICE_ATTR_2(in6_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
370 | max16065_set_limit, 0, 6); | 369 | max16065_set_limit, 0, 6); |
371 | static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 370 | static SENSOR_DEVICE_ATTR_2(in7_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
372 | max16065_set_limit, 0, 7); | 371 | max16065_set_limit, 0, 7); |
373 | static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 372 | static SENSOR_DEVICE_ATTR_2(in8_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
374 | max16065_set_limit, 0, 8); | 373 | max16065_set_limit, 0, 8); |
375 | static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 374 | static SENSOR_DEVICE_ATTR_2(in9_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
376 | max16065_set_limit, 0, 9); | 375 | max16065_set_limit, 0, 9); |
377 | static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 376 | static SENSOR_DEVICE_ATTR_2(in10_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
378 | max16065_set_limit, 0, 10); | 377 | max16065_set_limit, 0, 10); |
379 | static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, max16065_show_limit, | 378 | static SENSOR_DEVICE_ATTR_2(in11_max, S_IWUSR | S_IRUGO, max16065_show_limit, |
380 | max16065_set_limit, 0, 11); | 379 | max16065_set_limit, 0, 11); |
381 | 380 | ||
382 | /* alarms */ | 381 | /* alarms */ |
383 | static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, max16065_show_alarm, NULL, | 382 | static SENSOR_DEVICE_ATTR_2(in0_alarm, S_IRUGO, max16065_show_alarm, NULL, |
384 | 0, 0); | 383 | 0, 0); |
385 | static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, max16065_show_alarm, NULL, | 384 | static SENSOR_DEVICE_ATTR_2(in1_alarm, S_IRUGO, max16065_show_alarm, NULL, |
386 | 0, 1); | 385 | 0, 1); |
387 | static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, max16065_show_alarm, NULL, | 386 | static SENSOR_DEVICE_ATTR_2(in2_alarm, S_IRUGO, max16065_show_alarm, NULL, |
388 | 0, 2); | 387 | 0, 2); |
389 | static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, max16065_show_alarm, NULL, | 388 | static SENSOR_DEVICE_ATTR_2(in3_alarm, S_IRUGO, max16065_show_alarm, NULL, |
390 | 0, 3); | 389 | 0, 3); |
391 | static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, max16065_show_alarm, NULL, | 390 | static SENSOR_DEVICE_ATTR_2(in4_alarm, S_IRUGO, max16065_show_alarm, NULL, |
392 | 0, 4); | 391 | 0, 4); |
393 | static SENSOR_DEVICE_ATTR_2(in5_alarm, S_IRUGO, max16065_show_alarm, NULL, | 392 | static SENSOR_DEVICE_ATTR_2(in5_alarm, S_IRUGO, max16065_show_alarm, NULL, |
394 | 0, 5); | 393 | 0, 5); |
395 | static SENSOR_DEVICE_ATTR_2(in6_alarm, S_IRUGO, max16065_show_alarm, NULL, | 394 | static SENSOR_DEVICE_ATTR_2(in6_alarm, S_IRUGO, max16065_show_alarm, NULL, |
396 | 0, 6); | 395 | 0, 6); |
397 | static SENSOR_DEVICE_ATTR_2(in7_alarm, S_IRUGO, max16065_show_alarm, NULL, | 396 | static SENSOR_DEVICE_ATTR_2(in7_alarm, S_IRUGO, max16065_show_alarm, NULL, |
398 | 0, 7); | 397 | 0, 7); |
399 | static SENSOR_DEVICE_ATTR_2(in8_alarm, S_IRUGO, max16065_show_alarm, NULL, | 398 | static SENSOR_DEVICE_ATTR_2(in8_alarm, S_IRUGO, max16065_show_alarm, NULL, |
400 | 1, 0); | 399 | 1, 0); |
401 | static SENSOR_DEVICE_ATTR_2(in9_alarm, S_IRUGO, max16065_show_alarm, NULL, | 400 | static SENSOR_DEVICE_ATTR_2(in9_alarm, S_IRUGO, max16065_show_alarm, NULL, |
402 | 1, 1); | 401 | 1, 1); |
403 | static SENSOR_DEVICE_ATTR_2(in10_alarm, S_IRUGO, max16065_show_alarm, NULL, | 402 | static SENSOR_DEVICE_ATTR_2(in10_alarm, S_IRUGO, max16065_show_alarm, NULL, |
404 | 1, 2); | 403 | 1, 2); |
405 | static SENSOR_DEVICE_ATTR_2(in11_alarm, S_IRUGO, max16065_show_alarm, NULL, | 404 | static SENSOR_DEVICE_ATTR_2(in11_alarm, S_IRUGO, max16065_show_alarm, NULL, |
406 | 1, 3); | 405 | 1, 3); |
407 | 406 | ||
408 | /* Current and alarm */ | 407 | /* Current and alarm */ |
409 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, max16065_show_current, NULL, 0); | 408 | static SENSOR_DEVICE_ATTR(curr1_input, S_IRUGO, max16065_show_current, NULL, 0); |
410 | static SENSOR_DEVICE_ATTR_2(curr1_alarm, S_IRUGO, max16065_show_alarm, NULL, | 409 | static SENSOR_DEVICE_ATTR_2(curr1_alarm, S_IRUGO, max16065_show_alarm, NULL, |
411 | 1, 4); | 410 | 1, 4); |
412 | 411 | ||
413 | /* | 412 | /* |
414 | * Finally, construct an array of pointers to members of the above objects, | 413 | * Finally, construct an array of pointers to members of the above objects, |
415 | * as required for sysfs_create_group() | 414 | * as required for sysfs_create_group() |
416 | */ | 415 | */ |
417 | static struct attribute *max16065_basic_attributes[] = { | 416 | static struct attribute *max16065_basic_attributes[] = { |
418 | &sensor_dev_attr_in0_input.dev_attr.attr, | 417 | &sensor_dev_attr_in0_input.dev_attr.attr, |
419 | &sensor_dev_attr_in0_lcrit.dev_attr.attr, | 418 | &sensor_dev_attr_in0_lcrit.dev_attr.attr, |
420 | &sensor_dev_attr_in0_crit.dev_attr.attr, | 419 | &sensor_dev_attr_in0_crit.dev_attr.attr, |
421 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | 420 | &sensor_dev_attr_in0_alarm.dev_attr.attr, |
422 | 421 | ||
423 | &sensor_dev_attr_in1_input.dev_attr.attr, | 422 | &sensor_dev_attr_in1_input.dev_attr.attr, |
424 | &sensor_dev_attr_in1_lcrit.dev_attr.attr, | 423 | &sensor_dev_attr_in1_lcrit.dev_attr.attr, |
425 | &sensor_dev_attr_in1_crit.dev_attr.attr, | 424 | &sensor_dev_attr_in1_crit.dev_attr.attr, |
426 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | 425 | &sensor_dev_attr_in1_alarm.dev_attr.attr, |
427 | 426 | ||
428 | &sensor_dev_attr_in2_input.dev_attr.attr, | 427 | &sensor_dev_attr_in2_input.dev_attr.attr, |
429 | &sensor_dev_attr_in2_lcrit.dev_attr.attr, | 428 | &sensor_dev_attr_in2_lcrit.dev_attr.attr, |
430 | &sensor_dev_attr_in2_crit.dev_attr.attr, | 429 | &sensor_dev_attr_in2_crit.dev_attr.attr, |
431 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | 430 | &sensor_dev_attr_in2_alarm.dev_attr.attr, |
432 | 431 | ||
433 | &sensor_dev_attr_in3_input.dev_attr.attr, | 432 | &sensor_dev_attr_in3_input.dev_attr.attr, |
434 | &sensor_dev_attr_in3_lcrit.dev_attr.attr, | 433 | &sensor_dev_attr_in3_lcrit.dev_attr.attr, |
435 | &sensor_dev_attr_in3_crit.dev_attr.attr, | 434 | &sensor_dev_attr_in3_crit.dev_attr.attr, |
436 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | 435 | &sensor_dev_attr_in3_alarm.dev_attr.attr, |
437 | 436 | ||
438 | &sensor_dev_attr_in4_input.dev_attr.attr, | 437 | &sensor_dev_attr_in4_input.dev_attr.attr, |
439 | &sensor_dev_attr_in4_lcrit.dev_attr.attr, | 438 | &sensor_dev_attr_in4_lcrit.dev_attr.attr, |
440 | &sensor_dev_attr_in4_crit.dev_attr.attr, | 439 | &sensor_dev_attr_in4_crit.dev_attr.attr, |
441 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | 440 | &sensor_dev_attr_in4_alarm.dev_attr.attr, |
442 | 441 | ||
443 | &sensor_dev_attr_in5_input.dev_attr.attr, | 442 | &sensor_dev_attr_in5_input.dev_attr.attr, |
444 | &sensor_dev_attr_in5_lcrit.dev_attr.attr, | 443 | &sensor_dev_attr_in5_lcrit.dev_attr.attr, |
445 | &sensor_dev_attr_in5_crit.dev_attr.attr, | 444 | &sensor_dev_attr_in5_crit.dev_attr.attr, |
446 | &sensor_dev_attr_in5_alarm.dev_attr.attr, | 445 | &sensor_dev_attr_in5_alarm.dev_attr.attr, |
447 | 446 | ||
448 | &sensor_dev_attr_in6_input.dev_attr.attr, | 447 | &sensor_dev_attr_in6_input.dev_attr.attr, |
449 | &sensor_dev_attr_in6_lcrit.dev_attr.attr, | 448 | &sensor_dev_attr_in6_lcrit.dev_attr.attr, |
450 | &sensor_dev_attr_in6_crit.dev_attr.attr, | 449 | &sensor_dev_attr_in6_crit.dev_attr.attr, |
451 | &sensor_dev_attr_in6_alarm.dev_attr.attr, | 450 | &sensor_dev_attr_in6_alarm.dev_attr.attr, |
452 | 451 | ||
453 | &sensor_dev_attr_in7_input.dev_attr.attr, | 452 | &sensor_dev_attr_in7_input.dev_attr.attr, |
454 | &sensor_dev_attr_in7_lcrit.dev_attr.attr, | 453 | &sensor_dev_attr_in7_lcrit.dev_attr.attr, |
455 | &sensor_dev_attr_in7_crit.dev_attr.attr, | 454 | &sensor_dev_attr_in7_crit.dev_attr.attr, |
456 | &sensor_dev_attr_in7_alarm.dev_attr.attr, | 455 | &sensor_dev_attr_in7_alarm.dev_attr.attr, |
457 | 456 | ||
458 | &sensor_dev_attr_in8_input.dev_attr.attr, | 457 | &sensor_dev_attr_in8_input.dev_attr.attr, |
459 | &sensor_dev_attr_in8_lcrit.dev_attr.attr, | 458 | &sensor_dev_attr_in8_lcrit.dev_attr.attr, |
460 | &sensor_dev_attr_in8_crit.dev_attr.attr, | 459 | &sensor_dev_attr_in8_crit.dev_attr.attr, |
461 | &sensor_dev_attr_in8_alarm.dev_attr.attr, | 460 | &sensor_dev_attr_in8_alarm.dev_attr.attr, |
462 | 461 | ||
463 | &sensor_dev_attr_in9_input.dev_attr.attr, | 462 | &sensor_dev_attr_in9_input.dev_attr.attr, |
464 | &sensor_dev_attr_in9_lcrit.dev_attr.attr, | 463 | &sensor_dev_attr_in9_lcrit.dev_attr.attr, |
465 | &sensor_dev_attr_in9_crit.dev_attr.attr, | 464 | &sensor_dev_attr_in9_crit.dev_attr.attr, |
466 | &sensor_dev_attr_in9_alarm.dev_attr.attr, | 465 | &sensor_dev_attr_in9_alarm.dev_attr.attr, |
467 | 466 | ||
468 | &sensor_dev_attr_in10_input.dev_attr.attr, | 467 | &sensor_dev_attr_in10_input.dev_attr.attr, |
469 | &sensor_dev_attr_in10_lcrit.dev_attr.attr, | 468 | &sensor_dev_attr_in10_lcrit.dev_attr.attr, |
470 | &sensor_dev_attr_in10_crit.dev_attr.attr, | 469 | &sensor_dev_attr_in10_crit.dev_attr.attr, |
471 | &sensor_dev_attr_in10_alarm.dev_attr.attr, | 470 | &sensor_dev_attr_in10_alarm.dev_attr.attr, |
472 | 471 | ||
473 | &sensor_dev_attr_in11_input.dev_attr.attr, | 472 | &sensor_dev_attr_in11_input.dev_attr.attr, |
474 | &sensor_dev_attr_in11_lcrit.dev_attr.attr, | 473 | &sensor_dev_attr_in11_lcrit.dev_attr.attr, |
475 | &sensor_dev_attr_in11_crit.dev_attr.attr, | 474 | &sensor_dev_attr_in11_crit.dev_attr.attr, |
476 | &sensor_dev_attr_in11_alarm.dev_attr.attr, | 475 | &sensor_dev_attr_in11_alarm.dev_attr.attr, |
477 | 476 | ||
478 | NULL | 477 | NULL |
479 | }; | 478 | }; |
480 | 479 | ||
481 | static struct attribute *max16065_current_attributes[] = { | 480 | static struct attribute *max16065_current_attributes[] = { |
482 | &sensor_dev_attr_in12_input.dev_attr.attr, | 481 | &sensor_dev_attr_in12_input.dev_attr.attr, |
483 | &sensor_dev_attr_curr1_input.dev_attr.attr, | 482 | &sensor_dev_attr_curr1_input.dev_attr.attr, |
484 | &sensor_dev_attr_curr1_alarm.dev_attr.attr, | 483 | &sensor_dev_attr_curr1_alarm.dev_attr.attr, |
485 | NULL | 484 | NULL |
486 | }; | 485 | }; |
487 | 486 | ||
488 | static struct attribute *max16065_min_attributes[] = { | 487 | static struct attribute *max16065_min_attributes[] = { |
489 | &sensor_dev_attr_in0_min.dev_attr.attr, | 488 | &sensor_dev_attr_in0_min.dev_attr.attr, |
490 | &sensor_dev_attr_in1_min.dev_attr.attr, | 489 | &sensor_dev_attr_in1_min.dev_attr.attr, |
491 | &sensor_dev_attr_in2_min.dev_attr.attr, | 490 | &sensor_dev_attr_in2_min.dev_attr.attr, |
492 | &sensor_dev_attr_in3_min.dev_attr.attr, | 491 | &sensor_dev_attr_in3_min.dev_attr.attr, |
493 | &sensor_dev_attr_in4_min.dev_attr.attr, | 492 | &sensor_dev_attr_in4_min.dev_attr.attr, |
494 | &sensor_dev_attr_in5_min.dev_attr.attr, | 493 | &sensor_dev_attr_in5_min.dev_attr.attr, |
495 | &sensor_dev_attr_in6_min.dev_attr.attr, | 494 | &sensor_dev_attr_in6_min.dev_attr.attr, |
496 | &sensor_dev_attr_in7_min.dev_attr.attr, | 495 | &sensor_dev_attr_in7_min.dev_attr.attr, |
497 | &sensor_dev_attr_in8_min.dev_attr.attr, | 496 | &sensor_dev_attr_in8_min.dev_attr.attr, |
498 | &sensor_dev_attr_in9_min.dev_attr.attr, | 497 | &sensor_dev_attr_in9_min.dev_attr.attr, |
499 | &sensor_dev_attr_in10_min.dev_attr.attr, | 498 | &sensor_dev_attr_in10_min.dev_attr.attr, |
500 | &sensor_dev_attr_in11_min.dev_attr.attr, | 499 | &sensor_dev_attr_in11_min.dev_attr.attr, |
501 | NULL | 500 | NULL |
502 | }; | 501 | }; |
503 | 502 | ||
504 | static struct attribute *max16065_max_attributes[] = { | 503 | static struct attribute *max16065_max_attributes[] = { |
505 | &sensor_dev_attr_in0_max.dev_attr.attr, | 504 | &sensor_dev_attr_in0_max.dev_attr.attr, |
506 | &sensor_dev_attr_in1_max.dev_attr.attr, | 505 | &sensor_dev_attr_in1_max.dev_attr.attr, |
507 | &sensor_dev_attr_in2_max.dev_attr.attr, | 506 | &sensor_dev_attr_in2_max.dev_attr.attr, |
508 | &sensor_dev_attr_in3_max.dev_attr.attr, | 507 | &sensor_dev_attr_in3_max.dev_attr.attr, |
509 | &sensor_dev_attr_in4_max.dev_attr.attr, | 508 | &sensor_dev_attr_in4_max.dev_attr.attr, |
510 | &sensor_dev_attr_in5_max.dev_attr.attr, | 509 | &sensor_dev_attr_in5_max.dev_attr.attr, |
511 | &sensor_dev_attr_in6_max.dev_attr.attr, | 510 | &sensor_dev_attr_in6_max.dev_attr.attr, |
512 | &sensor_dev_attr_in7_max.dev_attr.attr, | 511 | &sensor_dev_attr_in7_max.dev_attr.attr, |
513 | &sensor_dev_attr_in8_max.dev_attr.attr, | 512 | &sensor_dev_attr_in8_max.dev_attr.attr, |
514 | &sensor_dev_attr_in9_max.dev_attr.attr, | 513 | &sensor_dev_attr_in9_max.dev_attr.attr, |
515 | &sensor_dev_attr_in10_max.dev_attr.attr, | 514 | &sensor_dev_attr_in10_max.dev_attr.attr, |
516 | &sensor_dev_attr_in11_max.dev_attr.attr, | 515 | &sensor_dev_attr_in11_max.dev_attr.attr, |
517 | NULL | 516 | NULL |
518 | }; | 517 | }; |
519 | 518 | ||
520 | static const struct attribute_group max16065_basic_group = { | 519 | static const struct attribute_group max16065_basic_group = { |
521 | .attrs = max16065_basic_attributes, | 520 | .attrs = max16065_basic_attributes, |
522 | }; | 521 | }; |
523 | 522 | ||
524 | static const struct attribute_group max16065_current_group = { | 523 | static const struct attribute_group max16065_current_group = { |
525 | .attrs = max16065_current_attributes, | 524 | .attrs = max16065_current_attributes, |
526 | }; | 525 | }; |
527 | 526 | ||
528 | static const struct attribute_group max16065_min_group = { | 527 | static const struct attribute_group max16065_min_group = { |
529 | .attrs = max16065_min_attributes, | 528 | .attrs = max16065_min_attributes, |
530 | }; | 529 | }; |
531 | 530 | ||
532 | static const struct attribute_group max16065_max_group = { | 531 | static const struct attribute_group max16065_max_group = { |
533 | .attrs = max16065_max_attributes, | 532 | .attrs = max16065_max_attributes, |
534 | }; | 533 | }; |
535 | 534 | ||
536 | static void max16065_cleanup(struct i2c_client *client) | 535 | static void max16065_cleanup(struct i2c_client *client) |
537 | { | 536 | { |
538 | sysfs_remove_group(&client->dev.kobj, &max16065_max_group); | 537 | sysfs_remove_group(&client->dev.kobj, &max16065_max_group); |
539 | sysfs_remove_group(&client->dev.kobj, &max16065_min_group); | 538 | sysfs_remove_group(&client->dev.kobj, &max16065_min_group); |
540 | sysfs_remove_group(&client->dev.kobj, &max16065_current_group); | 539 | sysfs_remove_group(&client->dev.kobj, &max16065_current_group); |
541 | sysfs_remove_group(&client->dev.kobj, &max16065_basic_group); | 540 | sysfs_remove_group(&client->dev.kobj, &max16065_basic_group); |
542 | } | 541 | } |
543 | 542 | ||
544 | static int max16065_probe(struct i2c_client *client, | 543 | static int max16065_probe(struct i2c_client *client, |
545 | const struct i2c_device_id *id) | 544 | const struct i2c_device_id *id) |
546 | { | 545 | { |
547 | struct i2c_adapter *adapter = client->adapter; | 546 | struct i2c_adapter *adapter = client->adapter; |
548 | struct max16065_data *data; | 547 | struct max16065_data *data; |
549 | int i, j, val, ret; | 548 | int i, j, val, ret; |
550 | bool have_secondary; /* true if chip has secondary limits */ | 549 | bool have_secondary; /* true if chip has secondary limits */ |
551 | bool secondary_is_max = false; /* secondary limits reflect max */ | 550 | bool secondary_is_max = false; /* secondary limits reflect max */ |
552 | 551 | ||
553 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | 552 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
554 | | I2C_FUNC_SMBUS_READ_WORD_DATA)) | 553 | | I2C_FUNC_SMBUS_READ_WORD_DATA)) |
555 | return -ENODEV; | 554 | return -ENODEV; |
556 | 555 | ||
557 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | 556 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); |
558 | if (unlikely(!data)) | 557 | if (unlikely(!data)) |
559 | return -ENOMEM; | 558 | return -ENOMEM; |
560 | 559 | ||
561 | i2c_set_clientdata(client, data); | 560 | i2c_set_clientdata(client, data); |
562 | mutex_init(&data->update_lock); | 561 | mutex_init(&data->update_lock); |
563 | 562 | ||
564 | data->num_adc = max16065_num_adc[id->driver_data]; | 563 | data->num_adc = max16065_num_adc[id->driver_data]; |
565 | data->have_current = max16065_have_current[id->driver_data]; | 564 | data->have_current = max16065_have_current[id->driver_data]; |
566 | have_secondary = max16065_have_secondary[id->driver_data]; | 565 | have_secondary = max16065_have_secondary[id->driver_data]; |
567 | 566 | ||
568 | if (have_secondary) { | 567 | if (have_secondary) { |
569 | val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE); | 568 | val = i2c_smbus_read_byte_data(client, MAX16065_SW_ENABLE); |
570 | if (unlikely(val < 0)) | 569 | if (unlikely(val < 0)) |
571 | return val; | 570 | return val; |
572 | secondary_is_max = val & MAX16065_WARNING_OV; | 571 | secondary_is_max = val & MAX16065_WARNING_OV; |
573 | } | 572 | } |
574 | 573 | ||
575 | /* Read scale registers, convert to range */ | 574 | /* Read scale registers, convert to range */ |
576 | for (i = 0; i < DIV_ROUND_UP(data->num_adc, 4); i++) { | 575 | for (i = 0; i < DIV_ROUND_UP(data->num_adc, 4); i++) { |
577 | val = i2c_smbus_read_byte_data(client, MAX16065_SCALE(i)); | 576 | val = i2c_smbus_read_byte_data(client, MAX16065_SCALE(i)); |
578 | if (unlikely(val < 0)) | 577 | if (unlikely(val < 0)) |
579 | return val; | 578 | return val; |
580 | for (j = 0; j < 4 && i * 4 + j < data->num_adc; j++) { | 579 | for (j = 0; j < 4 && i * 4 + j < data->num_adc; j++) { |
581 | data->range[i * 4 + j] = | 580 | data->range[i * 4 + j] = |
582 | max16065_adc_range[(val >> (j * 2)) & 0x3]; | 581 | max16065_adc_range[(val >> (j * 2)) & 0x3]; |
583 | } | 582 | } |
584 | } | 583 | } |
585 | 584 | ||
586 | /* Read limits */ | 585 | /* Read limits */ |
587 | for (i = 0; i < MAX16065_NUM_LIMIT; i++) { | 586 | for (i = 0; i < MAX16065_NUM_LIMIT; i++) { |
588 | if (i == 0 && !have_secondary) | 587 | if (i == 0 && !have_secondary) |
589 | continue; | 588 | continue; |
590 | 589 | ||
591 | for (j = 0; j < data->num_adc; j++) { | 590 | for (j = 0; j < data->num_adc; j++) { |
592 | val = i2c_smbus_read_byte_data(client, | 591 | val = i2c_smbus_read_byte_data(client, |
593 | MAX16065_LIMIT(i, j)); | 592 | MAX16065_LIMIT(i, j)); |
594 | if (unlikely(val < 0)) | 593 | if (unlikely(val < 0)) |
595 | return val; | 594 | return val; |
596 | data->limit[i][j] = LIMIT_TO_MV(val, data->range[j]); | 595 | data->limit[i][j] = LIMIT_TO_MV(val, data->range[j]); |
597 | } | 596 | } |
598 | } | 597 | } |
599 | 598 | ||
600 | /* Register sysfs hooks */ | 599 | /* Register sysfs hooks */ |
601 | for (i = 0; i < data->num_adc * 4; i++) { | 600 | for (i = 0; i < data->num_adc * 4; i++) { |
602 | /* Do not create sysfs entry if channel is disabled */ | 601 | /* Do not create sysfs entry if channel is disabled */ |
603 | if (!data->range[i / 4]) | 602 | if (!data->range[i / 4]) |
604 | continue; | 603 | continue; |
605 | 604 | ||
606 | ret = sysfs_create_file(&client->dev.kobj, | 605 | ret = sysfs_create_file(&client->dev.kobj, |
607 | max16065_basic_attributes[i]); | 606 | max16065_basic_attributes[i]); |
608 | if (unlikely(ret)) | 607 | if (unlikely(ret)) |
609 | goto out; | 608 | goto out; |
610 | } | 609 | } |
611 | 610 | ||
612 | if (have_secondary) { | 611 | if (have_secondary) { |
613 | struct attribute **attr = secondary_is_max ? | 612 | struct attribute **attr = secondary_is_max ? |
614 | max16065_max_attributes : max16065_min_attributes; | 613 | max16065_max_attributes : max16065_min_attributes; |
615 | 614 | ||
616 | for (i = 0; i < data->num_adc; i++) { | 615 | for (i = 0; i < data->num_adc; i++) { |
617 | if (!data->range[i]) | 616 | if (!data->range[i]) |
618 | continue; | 617 | continue; |
619 | 618 | ||
620 | ret = sysfs_create_file(&client->dev.kobj, attr[i]); | 619 | ret = sysfs_create_file(&client->dev.kobj, attr[i]); |
621 | if (unlikely(ret)) | 620 | if (unlikely(ret)) |
622 | goto out; | 621 | goto out; |
623 | } | 622 | } |
624 | } | 623 | } |
625 | 624 | ||
626 | if (data->have_current) { | 625 | if (data->have_current) { |
627 | val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL); | 626 | val = i2c_smbus_read_byte_data(client, MAX16065_CURR_CONTROL); |
628 | if (unlikely(val < 0)) { | 627 | if (unlikely(val < 0)) { |
629 | ret = val; | 628 | ret = val; |
630 | goto out; | 629 | goto out; |
631 | } | 630 | } |
632 | if (val & MAX16065_CURR_ENABLE) { | 631 | if (val & MAX16065_CURR_ENABLE) { |
633 | /* | 632 | /* |
634 | * Current gain is 6, 12, 24, 48 based on values in | 633 | * Current gain is 6, 12, 24, 48 based on values in |
635 | * bit 2,3. | 634 | * bit 2,3. |
636 | */ | 635 | */ |
637 | data->curr_gain = 6 << ((val >> 2) & 0x03); | 636 | data->curr_gain = 6 << ((val >> 2) & 0x03); |
638 | data->range[MAX16065_NUM_ADC] | 637 | data->range[MAX16065_NUM_ADC] |
639 | = max16065_csp_adc_range[(val >> 1) & 0x01]; | 638 | = max16065_csp_adc_range[(val >> 1) & 0x01]; |
640 | ret = sysfs_create_group(&client->dev.kobj, | 639 | ret = sysfs_create_group(&client->dev.kobj, |
641 | &max16065_current_group); | 640 | &max16065_current_group); |
642 | if (unlikely(ret)) | 641 | if (unlikely(ret)) |
643 | goto out; | 642 | goto out; |
644 | } else { | 643 | } else { |
645 | data->have_current = false; | 644 | data->have_current = false; |
646 | } | 645 | } |
647 | } | 646 | } |
648 | 647 | ||
649 | data->hwmon_dev = hwmon_device_register(&client->dev); | 648 | data->hwmon_dev = hwmon_device_register(&client->dev); |
650 | if (unlikely(IS_ERR(data->hwmon_dev))) { | 649 | if (unlikely(IS_ERR(data->hwmon_dev))) { |
651 | ret = PTR_ERR(data->hwmon_dev); | 650 | ret = PTR_ERR(data->hwmon_dev); |
652 | goto out; | 651 | goto out; |
653 | } | 652 | } |
654 | return 0; | 653 | return 0; |
655 | 654 | ||
656 | out: | 655 | out: |
657 | max16065_cleanup(client); | 656 | max16065_cleanup(client); |
658 | return ret; | 657 | return ret; |
659 | } | 658 | } |
660 | 659 | ||
661 | static int max16065_remove(struct i2c_client *client) | 660 | static int max16065_remove(struct i2c_client *client) |
662 | { | 661 | { |
663 | struct max16065_data *data = i2c_get_clientdata(client); | 662 | struct max16065_data *data = i2c_get_clientdata(client); |
664 | 663 | ||
665 | hwmon_device_unregister(data->hwmon_dev); | 664 | hwmon_device_unregister(data->hwmon_dev); |
666 | max16065_cleanup(client); | 665 | max16065_cleanup(client); |
667 | 666 | ||
668 | return 0; | 667 | return 0; |
669 | } | 668 | } |
670 | 669 | ||
671 | static const struct i2c_device_id max16065_id[] = { | 670 | static const struct i2c_device_id max16065_id[] = { |
672 | { "max16065", max16065 }, | 671 | { "max16065", max16065 }, |
673 | { "max16066", max16066 }, | 672 | { "max16066", max16066 }, |
674 | { "max16067", max16067 }, | 673 | { "max16067", max16067 }, |
675 | { "max16068", max16068 }, | 674 | { "max16068", max16068 }, |
676 | { "max16070", max16070 }, | 675 | { "max16070", max16070 }, |
677 | { "max16071", max16071 }, | 676 | { "max16071", max16071 }, |
678 | { } | 677 | { } |
679 | }; | 678 | }; |
680 | 679 | ||
681 | MODULE_DEVICE_TABLE(i2c, max16065_id); | 680 | MODULE_DEVICE_TABLE(i2c, max16065_id); |
682 | 681 | ||
683 | /* This is the driver that will be inserted */ | 682 | /* This is the driver that will be inserted */ |
684 | static struct i2c_driver max16065_driver = { | 683 | static struct i2c_driver max16065_driver = { |
685 | .driver = { | 684 | .driver = { |
686 | .name = "max16065", | 685 | .name = "max16065", |
687 | }, | 686 | }, |
688 | .probe = max16065_probe, | 687 | .probe = max16065_probe, |
689 | .remove = max16065_remove, | 688 | .remove = max16065_remove, |
690 | .id_table = max16065_id, | 689 | .id_table = max16065_id, |
691 | }; | 690 | }; |
692 | 691 | ||
693 | module_i2c_driver(max16065_driver); | 692 | module_i2c_driver(max16065_driver); |
694 | 693 | ||
695 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); | 694 | MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); |
696 | MODULE_DESCRIPTION("MAX16065 driver"); | 695 | MODULE_DESCRIPTION("MAX16065 driver"); |
697 | MODULE_LICENSE("GPL"); | 696 | MODULE_LICENSE("GPL"); |
698 | 697 |
drivers/hwmon/pmbus/pmbus_core.c
1 | /* | 1 | /* |
2 | * Hardware monitoring driver for PMBus devices | 2 | * Hardware monitoring driver for PMBus devices |
3 | * | 3 | * |
4 | * Copyright (c) 2010, 2011 Ericsson AB. | 4 | * Copyright (c) 2010, 2011 Ericsson AB. |
5 | * | 5 | * |
6 | * This program is free software; you can redistribute it and/or modify | 6 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License as published by | 7 | * it under the terms of the GNU General Public License as published by |
8 | * the Free Software Foundation; either version 2 of the License, or | 8 | * the Free Software Foundation; either version 2 of the License, or |
9 | * (at your option) any later version. | 9 | * (at your option) any later version. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | 18 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
22 | #include <linux/module.h> | 22 | #include <linux/module.h> |
23 | #include <linux/init.h> | 23 | #include <linux/init.h> |
24 | #include <linux/err.h> | 24 | #include <linux/err.h> |
25 | #include <linux/slab.h> | 25 | #include <linux/slab.h> |
26 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
27 | #include <linux/hwmon.h> | 27 | #include <linux/hwmon.h> |
28 | #include <linux/hwmon-sysfs.h> | 28 | #include <linux/hwmon-sysfs.h> |
29 | #include <linux/delay.h> | ||
30 | #include <linux/jiffies.h> | 29 | #include <linux/jiffies.h> |
31 | #include <linux/i2c/pmbus.h> | 30 | #include <linux/i2c/pmbus.h> |
32 | #include "pmbus.h" | 31 | #include "pmbus.h" |
33 | 32 | ||
34 | /* | 33 | /* |
35 | * Constants needed to determine number of sensors, booleans, and labels. | 34 | * Constants needed to determine number of sensors, booleans, and labels. |
36 | */ | 35 | */ |
37 | #define PMBUS_MAX_INPUT_SENSORS 22 /* 10*volt, 7*curr, 5*power */ | 36 | #define PMBUS_MAX_INPUT_SENSORS 22 /* 10*volt, 7*curr, 5*power */ |
38 | #define PMBUS_VOUT_SENSORS_PER_PAGE 9 /* input, min, max, lcrit, | 37 | #define PMBUS_VOUT_SENSORS_PER_PAGE 9 /* input, min, max, lcrit, |
39 | crit, lowest, highest, avg, | 38 | crit, lowest, highest, avg, |
40 | reset */ | 39 | reset */ |
41 | #define PMBUS_IOUT_SENSORS_PER_PAGE 8 /* input, min, max, crit, | 40 | #define PMBUS_IOUT_SENSORS_PER_PAGE 8 /* input, min, max, crit, |
42 | lowest, highest, avg, | 41 | lowest, highest, avg, |
43 | reset */ | 42 | reset */ |
44 | #define PMBUS_POUT_SENSORS_PER_PAGE 7 /* input, cap, max, crit, | 43 | #define PMBUS_POUT_SENSORS_PER_PAGE 7 /* input, cap, max, crit, |
45 | * highest, avg, reset | 44 | * highest, avg, reset |
46 | */ | 45 | */ |
47 | #define PMBUS_MAX_SENSORS_PER_FAN 1 /* input */ | 46 | #define PMBUS_MAX_SENSORS_PER_FAN 1 /* input */ |
48 | #define PMBUS_MAX_SENSORS_PER_TEMP 9 /* input, min, max, lcrit, | 47 | #define PMBUS_MAX_SENSORS_PER_TEMP 9 /* input, min, max, lcrit, |
49 | * crit, lowest, highest, avg, | 48 | * crit, lowest, highest, avg, |
50 | * reset | 49 | * reset |
51 | */ | 50 | */ |
52 | 51 | ||
53 | #define PMBUS_MAX_INPUT_BOOLEANS 7 /* v: min_alarm, max_alarm, | 52 | #define PMBUS_MAX_INPUT_BOOLEANS 7 /* v: min_alarm, max_alarm, |
54 | lcrit_alarm, crit_alarm; | 53 | lcrit_alarm, crit_alarm; |
55 | c: alarm, crit_alarm; | 54 | c: alarm, crit_alarm; |
56 | p: crit_alarm */ | 55 | p: crit_alarm */ |
57 | #define PMBUS_VOUT_BOOLEANS_PER_PAGE 4 /* min_alarm, max_alarm, | 56 | #define PMBUS_VOUT_BOOLEANS_PER_PAGE 4 /* min_alarm, max_alarm, |
58 | lcrit_alarm, crit_alarm */ | 57 | lcrit_alarm, crit_alarm */ |
59 | #define PMBUS_IOUT_BOOLEANS_PER_PAGE 3 /* alarm, lcrit_alarm, | 58 | #define PMBUS_IOUT_BOOLEANS_PER_PAGE 3 /* alarm, lcrit_alarm, |
60 | crit_alarm */ | 59 | crit_alarm */ |
61 | #define PMBUS_POUT_BOOLEANS_PER_PAGE 3 /* cap_alarm, alarm, crit_alarm | 60 | #define PMBUS_POUT_BOOLEANS_PER_PAGE 3 /* cap_alarm, alarm, crit_alarm |
62 | */ | 61 | */ |
63 | #define PMBUS_MAX_BOOLEANS_PER_FAN 2 /* alarm, fault */ | 62 | #define PMBUS_MAX_BOOLEANS_PER_FAN 2 /* alarm, fault */ |
64 | #define PMBUS_MAX_BOOLEANS_PER_TEMP 4 /* min_alarm, max_alarm, | 63 | #define PMBUS_MAX_BOOLEANS_PER_TEMP 4 /* min_alarm, max_alarm, |
65 | lcrit_alarm, crit_alarm */ | 64 | lcrit_alarm, crit_alarm */ |
66 | 65 | ||
67 | #define PMBUS_MAX_INPUT_LABELS 4 /* vin, vcap, iin, pin */ | 66 | #define PMBUS_MAX_INPUT_LABELS 4 /* vin, vcap, iin, pin */ |
68 | 67 | ||
69 | /* | 68 | /* |
70 | * status, status_vout, status_iout, status_fans, status_fan34, and status_temp | 69 | * status, status_vout, status_iout, status_fans, status_fan34, and status_temp |
71 | * are paged. status_input is unpaged. | 70 | * are paged. status_input is unpaged. |
72 | */ | 71 | */ |
73 | #define PB_NUM_STATUS_REG (PMBUS_PAGES * 6 + 1) | 72 | #define PB_NUM_STATUS_REG (PMBUS_PAGES * 6 + 1) |
74 | 73 | ||
75 | /* | 74 | /* |
76 | * Index into status register array, per status register group | 75 | * Index into status register array, per status register group |
77 | */ | 76 | */ |
78 | #define PB_STATUS_BASE 0 | 77 | #define PB_STATUS_BASE 0 |
79 | #define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES) | 78 | #define PB_STATUS_VOUT_BASE (PB_STATUS_BASE + PMBUS_PAGES) |
80 | #define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) | 79 | #define PB_STATUS_IOUT_BASE (PB_STATUS_VOUT_BASE + PMBUS_PAGES) |
81 | #define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) | 80 | #define PB_STATUS_FAN_BASE (PB_STATUS_IOUT_BASE + PMBUS_PAGES) |
82 | #define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES) | 81 | #define PB_STATUS_FAN34_BASE (PB_STATUS_FAN_BASE + PMBUS_PAGES) |
83 | #define PB_STATUS_INPUT_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES) | 82 | #define PB_STATUS_INPUT_BASE (PB_STATUS_FAN34_BASE + PMBUS_PAGES) |
84 | #define PB_STATUS_TEMP_BASE (PB_STATUS_INPUT_BASE + 1) | 83 | #define PB_STATUS_TEMP_BASE (PB_STATUS_INPUT_BASE + 1) |
85 | 84 | ||
86 | #define PMBUS_NAME_SIZE 24 | 85 | #define PMBUS_NAME_SIZE 24 |
87 | 86 | ||
88 | struct pmbus_sensor { | 87 | struct pmbus_sensor { |
89 | char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ | 88 | char name[PMBUS_NAME_SIZE]; /* sysfs sensor name */ |
90 | struct sensor_device_attribute attribute; | 89 | struct sensor_device_attribute attribute; |
91 | u8 page; /* page number */ | 90 | u8 page; /* page number */ |
92 | u16 reg; /* register */ | 91 | u16 reg; /* register */ |
93 | enum pmbus_sensor_classes class; /* sensor class */ | 92 | enum pmbus_sensor_classes class; /* sensor class */ |
94 | bool update; /* runtime sensor update needed */ | 93 | bool update; /* runtime sensor update needed */ |
95 | int data; /* Sensor data. | 94 | int data; /* Sensor data. |
96 | Negative if there was a read error */ | 95 | Negative if there was a read error */ |
97 | }; | 96 | }; |
98 | 97 | ||
99 | struct pmbus_boolean { | 98 | struct pmbus_boolean { |
100 | char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ | 99 | char name[PMBUS_NAME_SIZE]; /* sysfs boolean name */ |
101 | struct sensor_device_attribute attribute; | 100 | struct sensor_device_attribute attribute; |
102 | }; | 101 | }; |
103 | 102 | ||
104 | struct pmbus_label { | 103 | struct pmbus_label { |
105 | char name[PMBUS_NAME_SIZE]; /* sysfs label name */ | 104 | char name[PMBUS_NAME_SIZE]; /* sysfs label name */ |
106 | struct sensor_device_attribute attribute; | 105 | struct sensor_device_attribute attribute; |
107 | char label[PMBUS_NAME_SIZE]; /* label */ | 106 | char label[PMBUS_NAME_SIZE]; /* label */ |
108 | }; | 107 | }; |
109 | 108 | ||
110 | struct pmbus_data { | 109 | struct pmbus_data { |
111 | struct device *hwmon_dev; | 110 | struct device *hwmon_dev; |
112 | 111 | ||
113 | u32 flags; /* from platform data */ | 112 | u32 flags; /* from platform data */ |
114 | 113 | ||
115 | int exponent; /* linear mode: exponent for output voltages */ | 114 | int exponent; /* linear mode: exponent for output voltages */ |
116 | 115 | ||
117 | const struct pmbus_driver_info *info; | 116 | const struct pmbus_driver_info *info; |
118 | 117 | ||
119 | int max_attributes; | 118 | int max_attributes; |
120 | int num_attributes; | 119 | int num_attributes; |
121 | struct attribute **attributes; | 120 | struct attribute **attributes; |
122 | struct attribute_group group; | 121 | struct attribute_group group; |
123 | 122 | ||
124 | /* | 123 | /* |
125 | * Sensors cover both sensor and limit registers. | 124 | * Sensors cover both sensor and limit registers. |
126 | */ | 125 | */ |
127 | int max_sensors; | 126 | int max_sensors; |
128 | int num_sensors; | 127 | int num_sensors; |
129 | struct pmbus_sensor *sensors; | 128 | struct pmbus_sensor *sensors; |
130 | /* | 129 | /* |
131 | * Booleans are used for alarms. | 130 | * Booleans are used for alarms. |
132 | * Values are determined from status registers. | 131 | * Values are determined from status registers. |
133 | */ | 132 | */ |
134 | int max_booleans; | 133 | int max_booleans; |
135 | int num_booleans; | 134 | int num_booleans; |
136 | struct pmbus_boolean *booleans; | 135 | struct pmbus_boolean *booleans; |
137 | /* | 136 | /* |
138 | * Labels are used to map generic names (e.g., "in1") | 137 | * Labels are used to map generic names (e.g., "in1") |
139 | * to PMBus specific names (e.g., "vin" or "vout1"). | 138 | * to PMBus specific names (e.g., "vin" or "vout1"). |
140 | */ | 139 | */ |
141 | int max_labels; | 140 | int max_labels; |
142 | int num_labels; | 141 | int num_labels; |
143 | struct pmbus_label *labels; | 142 | struct pmbus_label *labels; |
144 | 143 | ||
145 | struct mutex update_lock; | 144 | struct mutex update_lock; |
146 | bool valid; | 145 | bool valid; |
147 | unsigned long last_updated; /* in jiffies */ | 146 | unsigned long last_updated; /* in jiffies */ |
148 | 147 | ||
149 | /* | 148 | /* |
150 | * A single status register covers multiple attributes, | 149 | * A single status register covers multiple attributes, |
151 | * so we keep them all together. | 150 | * so we keep them all together. |
152 | */ | 151 | */ |
153 | u8 status[PB_NUM_STATUS_REG]; | 152 | u8 status[PB_NUM_STATUS_REG]; |
154 | 153 | ||
155 | u8 currpage; | 154 | u8 currpage; |
156 | }; | 155 | }; |
157 | 156 | ||
158 | int pmbus_set_page(struct i2c_client *client, u8 page) | 157 | int pmbus_set_page(struct i2c_client *client, u8 page) |
159 | { | 158 | { |
160 | struct pmbus_data *data = i2c_get_clientdata(client); | 159 | struct pmbus_data *data = i2c_get_clientdata(client); |
161 | int rv = 0; | 160 | int rv = 0; |
162 | int newpage; | 161 | int newpage; |
163 | 162 | ||
164 | if (page != data->currpage) { | 163 | if (page != data->currpage) { |
165 | rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); | 164 | rv = i2c_smbus_write_byte_data(client, PMBUS_PAGE, page); |
166 | newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); | 165 | newpage = i2c_smbus_read_byte_data(client, PMBUS_PAGE); |
167 | if (newpage != page) | 166 | if (newpage != page) |
168 | rv = -EIO; | 167 | rv = -EIO; |
169 | else | 168 | else |
170 | data->currpage = page; | 169 | data->currpage = page; |
171 | } | 170 | } |
172 | return rv; | 171 | return rv; |
173 | } | 172 | } |
174 | EXPORT_SYMBOL_GPL(pmbus_set_page); | 173 | EXPORT_SYMBOL_GPL(pmbus_set_page); |
175 | 174 | ||
176 | int pmbus_write_byte(struct i2c_client *client, int page, u8 value) | 175 | int pmbus_write_byte(struct i2c_client *client, int page, u8 value) |
177 | { | 176 | { |
178 | int rv; | 177 | int rv; |
179 | 178 | ||
180 | if (page >= 0) { | 179 | if (page >= 0) { |
181 | rv = pmbus_set_page(client, page); | 180 | rv = pmbus_set_page(client, page); |
182 | if (rv < 0) | 181 | if (rv < 0) |
183 | return rv; | 182 | return rv; |
184 | } | 183 | } |
185 | 184 | ||
186 | return i2c_smbus_write_byte(client, value); | 185 | return i2c_smbus_write_byte(client, value); |
187 | } | 186 | } |
188 | EXPORT_SYMBOL_GPL(pmbus_write_byte); | 187 | EXPORT_SYMBOL_GPL(pmbus_write_byte); |
189 | 188 | ||
190 | /* | 189 | /* |
191 | * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if | 190 | * _pmbus_write_byte() is similar to pmbus_write_byte(), but checks if |
192 | * a device specific mapping funcion exists and calls it if necessary. | 191 | * a device specific mapping funcion exists and calls it if necessary. |
193 | */ | 192 | */ |
194 | static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) | 193 | static int _pmbus_write_byte(struct i2c_client *client, int page, u8 value) |
195 | { | 194 | { |
196 | struct pmbus_data *data = i2c_get_clientdata(client); | 195 | struct pmbus_data *data = i2c_get_clientdata(client); |
197 | const struct pmbus_driver_info *info = data->info; | 196 | const struct pmbus_driver_info *info = data->info; |
198 | int status; | 197 | int status; |
199 | 198 | ||
200 | if (info->write_byte) { | 199 | if (info->write_byte) { |
201 | status = info->write_byte(client, page, value); | 200 | status = info->write_byte(client, page, value); |
202 | if (status != -ENODATA) | 201 | if (status != -ENODATA) |
203 | return status; | 202 | return status; |
204 | } | 203 | } |
205 | return pmbus_write_byte(client, page, value); | 204 | return pmbus_write_byte(client, page, value); |
206 | } | 205 | } |
207 | 206 | ||
208 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word) | 207 | int pmbus_write_word_data(struct i2c_client *client, u8 page, u8 reg, u16 word) |
209 | { | 208 | { |
210 | int rv; | 209 | int rv; |
211 | 210 | ||
212 | rv = pmbus_set_page(client, page); | 211 | rv = pmbus_set_page(client, page); |
213 | if (rv < 0) | 212 | if (rv < 0) |
214 | return rv; | 213 | return rv; |
215 | 214 | ||
216 | return i2c_smbus_write_word_data(client, reg, word); | 215 | return i2c_smbus_write_word_data(client, reg, word); |
217 | } | 216 | } |
218 | EXPORT_SYMBOL_GPL(pmbus_write_word_data); | 217 | EXPORT_SYMBOL_GPL(pmbus_write_word_data); |
219 | 218 | ||
220 | /* | 219 | /* |
221 | * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if | 220 | * _pmbus_write_word_data() is similar to pmbus_write_word_data(), but checks if |
222 | * a device specific mapping function exists and calls it if necessary. | 221 | * a device specific mapping function exists and calls it if necessary. |
223 | */ | 222 | */ |
224 | static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, | 223 | static int _pmbus_write_word_data(struct i2c_client *client, int page, int reg, |
225 | u16 word) | 224 | u16 word) |
226 | { | 225 | { |
227 | struct pmbus_data *data = i2c_get_clientdata(client); | 226 | struct pmbus_data *data = i2c_get_clientdata(client); |
228 | const struct pmbus_driver_info *info = data->info; | 227 | const struct pmbus_driver_info *info = data->info; |
229 | int status; | 228 | int status; |
230 | 229 | ||
231 | if (info->write_word_data) { | 230 | if (info->write_word_data) { |
232 | status = info->write_word_data(client, page, reg, word); | 231 | status = info->write_word_data(client, page, reg, word); |
233 | if (status != -ENODATA) | 232 | if (status != -ENODATA) |
234 | return status; | 233 | return status; |
235 | } | 234 | } |
236 | if (reg >= PMBUS_VIRT_BASE) | 235 | if (reg >= PMBUS_VIRT_BASE) |
237 | return -ENXIO; | 236 | return -ENXIO; |
238 | return pmbus_write_word_data(client, page, reg, word); | 237 | return pmbus_write_word_data(client, page, reg, word); |
239 | } | 238 | } |
240 | 239 | ||
241 | int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg) | 240 | int pmbus_read_word_data(struct i2c_client *client, u8 page, u8 reg) |
242 | { | 241 | { |
243 | int rv; | 242 | int rv; |
244 | 243 | ||
245 | rv = pmbus_set_page(client, page); | 244 | rv = pmbus_set_page(client, page); |
246 | if (rv < 0) | 245 | if (rv < 0) |
247 | return rv; | 246 | return rv; |
248 | 247 | ||
249 | return i2c_smbus_read_word_data(client, reg); | 248 | return i2c_smbus_read_word_data(client, reg); |
250 | } | 249 | } |
251 | EXPORT_SYMBOL_GPL(pmbus_read_word_data); | 250 | EXPORT_SYMBOL_GPL(pmbus_read_word_data); |
252 | 251 | ||
253 | /* | 252 | /* |
254 | * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if | 253 | * _pmbus_read_word_data() is similar to pmbus_read_word_data(), but checks if |
255 | * a device specific mapping function exists and calls it if necessary. | 254 | * a device specific mapping function exists and calls it if necessary. |
256 | */ | 255 | */ |
257 | static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) | 256 | static int _pmbus_read_word_data(struct i2c_client *client, int page, int reg) |
258 | { | 257 | { |
259 | struct pmbus_data *data = i2c_get_clientdata(client); | 258 | struct pmbus_data *data = i2c_get_clientdata(client); |
260 | const struct pmbus_driver_info *info = data->info; | 259 | const struct pmbus_driver_info *info = data->info; |
261 | int status; | 260 | int status; |
262 | 261 | ||
263 | if (info->read_word_data) { | 262 | if (info->read_word_data) { |
264 | status = info->read_word_data(client, page, reg); | 263 | status = info->read_word_data(client, page, reg); |
265 | if (status != -ENODATA) | 264 | if (status != -ENODATA) |
266 | return status; | 265 | return status; |
267 | } | 266 | } |
268 | if (reg >= PMBUS_VIRT_BASE) | 267 | if (reg >= PMBUS_VIRT_BASE) |
269 | return -ENXIO; | 268 | return -ENXIO; |
270 | return pmbus_read_word_data(client, page, reg); | 269 | return pmbus_read_word_data(client, page, reg); |
271 | } | 270 | } |
272 | 271 | ||
273 | int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) | 272 | int pmbus_read_byte_data(struct i2c_client *client, int page, u8 reg) |
274 | { | 273 | { |
275 | int rv; | 274 | int rv; |
276 | 275 | ||
277 | if (page >= 0) { | 276 | if (page >= 0) { |
278 | rv = pmbus_set_page(client, page); | 277 | rv = pmbus_set_page(client, page); |
279 | if (rv < 0) | 278 | if (rv < 0) |
280 | return rv; | 279 | return rv; |
281 | } | 280 | } |
282 | 281 | ||
283 | return i2c_smbus_read_byte_data(client, reg); | 282 | return i2c_smbus_read_byte_data(client, reg); |
284 | } | 283 | } |
285 | EXPORT_SYMBOL_GPL(pmbus_read_byte_data); | 284 | EXPORT_SYMBOL_GPL(pmbus_read_byte_data); |
286 | 285 | ||
287 | /* | 286 | /* |
288 | * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if | 287 | * _pmbus_read_byte_data() is similar to pmbus_read_byte_data(), but checks if |
289 | * a device specific mapping function exists and calls it if necessary. | 288 | * a device specific mapping function exists and calls it if necessary. |
290 | */ | 289 | */ |
291 | static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) | 290 | static int _pmbus_read_byte_data(struct i2c_client *client, int page, int reg) |
292 | { | 291 | { |
293 | struct pmbus_data *data = i2c_get_clientdata(client); | 292 | struct pmbus_data *data = i2c_get_clientdata(client); |
294 | const struct pmbus_driver_info *info = data->info; | 293 | const struct pmbus_driver_info *info = data->info; |
295 | int status; | 294 | int status; |
296 | 295 | ||
297 | if (info->read_byte_data) { | 296 | if (info->read_byte_data) { |
298 | status = info->read_byte_data(client, page, reg); | 297 | status = info->read_byte_data(client, page, reg); |
299 | if (status != -ENODATA) | 298 | if (status != -ENODATA) |
300 | return status; | 299 | return status; |
301 | } | 300 | } |
302 | return pmbus_read_byte_data(client, page, reg); | 301 | return pmbus_read_byte_data(client, page, reg); |
303 | } | 302 | } |
304 | 303 | ||
305 | static void pmbus_clear_fault_page(struct i2c_client *client, int page) | 304 | static void pmbus_clear_fault_page(struct i2c_client *client, int page) |
306 | { | 305 | { |
307 | _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); | 306 | _pmbus_write_byte(client, page, PMBUS_CLEAR_FAULTS); |
308 | } | 307 | } |
309 | 308 | ||
310 | void pmbus_clear_faults(struct i2c_client *client) | 309 | void pmbus_clear_faults(struct i2c_client *client) |
311 | { | 310 | { |
312 | struct pmbus_data *data = i2c_get_clientdata(client); | 311 | struct pmbus_data *data = i2c_get_clientdata(client); |
313 | int i; | 312 | int i; |
314 | 313 | ||
315 | for (i = 0; i < data->info->pages; i++) | 314 | for (i = 0; i < data->info->pages; i++) |
316 | pmbus_clear_fault_page(client, i); | 315 | pmbus_clear_fault_page(client, i); |
317 | } | 316 | } |
318 | EXPORT_SYMBOL_GPL(pmbus_clear_faults); | 317 | EXPORT_SYMBOL_GPL(pmbus_clear_faults); |
319 | 318 | ||
320 | static int pmbus_check_status_cml(struct i2c_client *client) | 319 | static int pmbus_check_status_cml(struct i2c_client *client) |
321 | { | 320 | { |
322 | int status, status2; | 321 | int status, status2; |
323 | 322 | ||
324 | status = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_BYTE); | 323 | status = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_BYTE); |
325 | if (status < 0 || (status & PB_STATUS_CML)) { | 324 | if (status < 0 || (status & PB_STATUS_CML)) { |
326 | status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); | 325 | status2 = _pmbus_read_byte_data(client, -1, PMBUS_STATUS_CML); |
327 | if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) | 326 | if (status2 < 0 || (status2 & PB_CML_FAULT_INVALID_COMMAND)) |
328 | return -EIO; | 327 | return -EIO; |
329 | } | 328 | } |
330 | return 0; | 329 | return 0; |
331 | } | 330 | } |
332 | 331 | ||
333 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg) | 332 | bool pmbus_check_byte_register(struct i2c_client *client, int page, int reg) |
334 | { | 333 | { |
335 | int rv; | 334 | int rv; |
336 | struct pmbus_data *data = i2c_get_clientdata(client); | 335 | struct pmbus_data *data = i2c_get_clientdata(client); |
337 | 336 | ||
338 | rv = _pmbus_read_byte_data(client, page, reg); | 337 | rv = _pmbus_read_byte_data(client, page, reg); |
339 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) | 338 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) |
340 | rv = pmbus_check_status_cml(client); | 339 | rv = pmbus_check_status_cml(client); |
341 | pmbus_clear_fault_page(client, -1); | 340 | pmbus_clear_fault_page(client, -1); |
342 | return rv >= 0; | 341 | return rv >= 0; |
343 | } | 342 | } |
344 | EXPORT_SYMBOL_GPL(pmbus_check_byte_register); | 343 | EXPORT_SYMBOL_GPL(pmbus_check_byte_register); |
345 | 344 | ||
346 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) | 345 | bool pmbus_check_word_register(struct i2c_client *client, int page, int reg) |
347 | { | 346 | { |
348 | int rv; | 347 | int rv; |
349 | struct pmbus_data *data = i2c_get_clientdata(client); | 348 | struct pmbus_data *data = i2c_get_clientdata(client); |
350 | 349 | ||
351 | rv = _pmbus_read_word_data(client, page, reg); | 350 | rv = _pmbus_read_word_data(client, page, reg); |
352 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) | 351 | if (rv >= 0 && !(data->flags & PMBUS_SKIP_STATUS_CHECK)) |
353 | rv = pmbus_check_status_cml(client); | 352 | rv = pmbus_check_status_cml(client); |
354 | pmbus_clear_fault_page(client, -1); | 353 | pmbus_clear_fault_page(client, -1); |
355 | return rv >= 0; | 354 | return rv >= 0; |
356 | } | 355 | } |
357 | EXPORT_SYMBOL_GPL(pmbus_check_word_register); | 356 | EXPORT_SYMBOL_GPL(pmbus_check_word_register); |
358 | 357 | ||
359 | const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client) | 358 | const struct pmbus_driver_info *pmbus_get_driver_info(struct i2c_client *client) |
360 | { | 359 | { |
361 | struct pmbus_data *data = i2c_get_clientdata(client); | 360 | struct pmbus_data *data = i2c_get_clientdata(client); |
362 | 361 | ||
363 | return data->info; | 362 | return data->info; |
364 | } | 363 | } |
365 | EXPORT_SYMBOL_GPL(pmbus_get_driver_info); | 364 | EXPORT_SYMBOL_GPL(pmbus_get_driver_info); |
366 | 365 | ||
367 | static struct pmbus_data *pmbus_update_device(struct device *dev) | 366 | static struct pmbus_data *pmbus_update_device(struct device *dev) |
368 | { | 367 | { |
369 | struct i2c_client *client = to_i2c_client(dev); | 368 | struct i2c_client *client = to_i2c_client(dev); |
370 | struct pmbus_data *data = i2c_get_clientdata(client); | 369 | struct pmbus_data *data = i2c_get_clientdata(client); |
371 | const struct pmbus_driver_info *info = data->info; | 370 | const struct pmbus_driver_info *info = data->info; |
372 | 371 | ||
373 | mutex_lock(&data->update_lock); | 372 | mutex_lock(&data->update_lock); |
374 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { | 373 | if (time_after(jiffies, data->last_updated + HZ) || !data->valid) { |
375 | int i; | 374 | int i; |
376 | 375 | ||
377 | for (i = 0; i < info->pages; i++) | 376 | for (i = 0; i < info->pages; i++) |
378 | data->status[PB_STATUS_BASE + i] | 377 | data->status[PB_STATUS_BASE + i] |
379 | = _pmbus_read_byte_data(client, i, | 378 | = _pmbus_read_byte_data(client, i, |
380 | PMBUS_STATUS_BYTE); | 379 | PMBUS_STATUS_BYTE); |
381 | for (i = 0; i < info->pages; i++) { | 380 | for (i = 0; i < info->pages; i++) { |
382 | if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT)) | 381 | if (!(info->func[i] & PMBUS_HAVE_STATUS_VOUT)) |
383 | continue; | 382 | continue; |
384 | data->status[PB_STATUS_VOUT_BASE + i] | 383 | data->status[PB_STATUS_VOUT_BASE + i] |
385 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_VOUT); | 384 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_VOUT); |
386 | } | 385 | } |
387 | for (i = 0; i < info->pages; i++) { | 386 | for (i = 0; i < info->pages; i++) { |
388 | if (!(info->func[i] & PMBUS_HAVE_STATUS_IOUT)) | 387 | if (!(info->func[i] & PMBUS_HAVE_STATUS_IOUT)) |
389 | continue; | 388 | continue; |
390 | data->status[PB_STATUS_IOUT_BASE + i] | 389 | data->status[PB_STATUS_IOUT_BASE + i] |
391 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_IOUT); | 390 | = _pmbus_read_byte_data(client, i, PMBUS_STATUS_IOUT); |
392 | } | 391 | } |
393 | for (i = 0; i < info->pages; i++) { | 392 | for (i = 0; i < info->pages; i++) { |
394 | if (!(info->func[i] & PMBUS_HAVE_STATUS_TEMP)) | 393 | if (!(info->func[i] & PMBUS_HAVE_STATUS_TEMP)) |
395 | continue; | 394 | continue; |
396 | data->status[PB_STATUS_TEMP_BASE + i] | 395 | data->status[PB_STATUS_TEMP_BASE + i] |
397 | = _pmbus_read_byte_data(client, i, | 396 | = _pmbus_read_byte_data(client, i, |
398 | PMBUS_STATUS_TEMPERATURE); | 397 | PMBUS_STATUS_TEMPERATURE); |
399 | } | 398 | } |
400 | for (i = 0; i < info->pages; i++) { | 399 | for (i = 0; i < info->pages; i++) { |
401 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN12)) | 400 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN12)) |
402 | continue; | 401 | continue; |
403 | data->status[PB_STATUS_FAN_BASE + i] | 402 | data->status[PB_STATUS_FAN_BASE + i] |
404 | = _pmbus_read_byte_data(client, i, | 403 | = _pmbus_read_byte_data(client, i, |
405 | PMBUS_STATUS_FAN_12); | 404 | PMBUS_STATUS_FAN_12); |
406 | } | 405 | } |
407 | 406 | ||
408 | for (i = 0; i < info->pages; i++) { | 407 | for (i = 0; i < info->pages; i++) { |
409 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN34)) | 408 | if (!(info->func[i] & PMBUS_HAVE_STATUS_FAN34)) |
410 | continue; | 409 | continue; |
411 | data->status[PB_STATUS_FAN34_BASE + i] | 410 | data->status[PB_STATUS_FAN34_BASE + i] |
412 | = _pmbus_read_byte_data(client, i, | 411 | = _pmbus_read_byte_data(client, i, |
413 | PMBUS_STATUS_FAN_34); | 412 | PMBUS_STATUS_FAN_34); |
414 | } | 413 | } |
415 | 414 | ||
416 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) | 415 | if (info->func[0] & PMBUS_HAVE_STATUS_INPUT) |
417 | data->status[PB_STATUS_INPUT_BASE] | 416 | data->status[PB_STATUS_INPUT_BASE] |
418 | = _pmbus_read_byte_data(client, 0, | 417 | = _pmbus_read_byte_data(client, 0, |
419 | PMBUS_STATUS_INPUT); | 418 | PMBUS_STATUS_INPUT); |
420 | 419 | ||
421 | for (i = 0; i < data->num_sensors; i++) { | 420 | for (i = 0; i < data->num_sensors; i++) { |
422 | struct pmbus_sensor *sensor = &data->sensors[i]; | 421 | struct pmbus_sensor *sensor = &data->sensors[i]; |
423 | 422 | ||
424 | if (!data->valid || sensor->update) | 423 | if (!data->valid || sensor->update) |
425 | sensor->data | 424 | sensor->data |
426 | = _pmbus_read_word_data(client, | 425 | = _pmbus_read_word_data(client, |
427 | sensor->page, | 426 | sensor->page, |
428 | sensor->reg); | 427 | sensor->reg); |
429 | } | 428 | } |
430 | pmbus_clear_faults(client); | 429 | pmbus_clear_faults(client); |
431 | data->last_updated = jiffies; | 430 | data->last_updated = jiffies; |
432 | data->valid = 1; | 431 | data->valid = 1; |
433 | } | 432 | } |
434 | mutex_unlock(&data->update_lock); | 433 | mutex_unlock(&data->update_lock); |
435 | return data; | 434 | return data; |
436 | } | 435 | } |
437 | 436 | ||
438 | /* | 437 | /* |
439 | * Convert linear sensor values to milli- or micro-units | 438 | * Convert linear sensor values to milli- or micro-units |
440 | * depending on sensor type. | 439 | * depending on sensor type. |
441 | */ | 440 | */ |
442 | static long pmbus_reg2data_linear(struct pmbus_data *data, | 441 | static long pmbus_reg2data_linear(struct pmbus_data *data, |
443 | struct pmbus_sensor *sensor) | 442 | struct pmbus_sensor *sensor) |
444 | { | 443 | { |
445 | s16 exponent; | 444 | s16 exponent; |
446 | s32 mantissa; | 445 | s32 mantissa; |
447 | long val; | 446 | long val; |
448 | 447 | ||
449 | if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ | 448 | if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ |
450 | exponent = data->exponent; | 449 | exponent = data->exponent; |
451 | mantissa = (u16) sensor->data; | 450 | mantissa = (u16) sensor->data; |
452 | } else { /* LINEAR11 */ | 451 | } else { /* LINEAR11 */ |
453 | exponent = ((s16)sensor->data) >> 11; | 452 | exponent = ((s16)sensor->data) >> 11; |
454 | mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; | 453 | mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; |
455 | } | 454 | } |
456 | 455 | ||
457 | val = mantissa; | 456 | val = mantissa; |
458 | 457 | ||
459 | /* scale result to milli-units for all sensors except fans */ | 458 | /* scale result to milli-units for all sensors except fans */ |
460 | if (sensor->class != PSC_FAN) | 459 | if (sensor->class != PSC_FAN) |
461 | val = val * 1000L; | 460 | val = val * 1000L; |
462 | 461 | ||
463 | /* scale result to micro-units for power sensors */ | 462 | /* scale result to micro-units for power sensors */ |
464 | if (sensor->class == PSC_POWER) | 463 | if (sensor->class == PSC_POWER) |
465 | val = val * 1000L; | 464 | val = val * 1000L; |
466 | 465 | ||
467 | if (exponent >= 0) | 466 | if (exponent >= 0) |
468 | val <<= exponent; | 467 | val <<= exponent; |
469 | else | 468 | else |
470 | val >>= -exponent; | 469 | val >>= -exponent; |
471 | 470 | ||
472 | return val; | 471 | return val; |
473 | } | 472 | } |
474 | 473 | ||
475 | /* | 474 | /* |
476 | * Convert direct sensor values to milli- or micro-units | 475 | * Convert direct sensor values to milli- or micro-units |
477 | * depending on sensor type. | 476 | * depending on sensor type. |
478 | */ | 477 | */ |
479 | static long pmbus_reg2data_direct(struct pmbus_data *data, | 478 | static long pmbus_reg2data_direct(struct pmbus_data *data, |
480 | struct pmbus_sensor *sensor) | 479 | struct pmbus_sensor *sensor) |
481 | { | 480 | { |
482 | long val = (s16) sensor->data; | 481 | long val = (s16) sensor->data; |
483 | long m, b, R; | 482 | long m, b, R; |
484 | 483 | ||
485 | m = data->info->m[sensor->class]; | 484 | m = data->info->m[sensor->class]; |
486 | b = data->info->b[sensor->class]; | 485 | b = data->info->b[sensor->class]; |
487 | R = data->info->R[sensor->class]; | 486 | R = data->info->R[sensor->class]; |
488 | 487 | ||
489 | if (m == 0) | 488 | if (m == 0) |
490 | return 0; | 489 | return 0; |
491 | 490 | ||
492 | /* X = 1/m * (Y * 10^-R - b) */ | 491 | /* X = 1/m * (Y * 10^-R - b) */ |
493 | R = -R; | 492 | R = -R; |
494 | /* scale result to milli-units for everything but fans */ | 493 | /* scale result to milli-units for everything but fans */ |
495 | if (sensor->class != PSC_FAN) { | 494 | if (sensor->class != PSC_FAN) { |
496 | R += 3; | 495 | R += 3; |
497 | b *= 1000; | 496 | b *= 1000; |
498 | } | 497 | } |
499 | 498 | ||
500 | /* scale result to micro-units for power sensors */ | 499 | /* scale result to micro-units for power sensors */ |
501 | if (sensor->class == PSC_POWER) { | 500 | if (sensor->class == PSC_POWER) { |
502 | R += 3; | 501 | R += 3; |
503 | b *= 1000; | 502 | b *= 1000; |
504 | } | 503 | } |
505 | 504 | ||
506 | while (R > 0) { | 505 | while (R > 0) { |
507 | val *= 10; | 506 | val *= 10; |
508 | R--; | 507 | R--; |
509 | } | 508 | } |
510 | while (R < 0) { | 509 | while (R < 0) { |
511 | val = DIV_ROUND_CLOSEST(val, 10); | 510 | val = DIV_ROUND_CLOSEST(val, 10); |
512 | R++; | 511 | R++; |
513 | } | 512 | } |
514 | 513 | ||
515 | return (val - b) / m; | 514 | return (val - b) / m; |
516 | } | 515 | } |
517 | 516 | ||
518 | /* | 517 | /* |
519 | * Convert VID sensor values to milli- or micro-units | 518 | * Convert VID sensor values to milli- or micro-units |
520 | * depending on sensor type. | 519 | * depending on sensor type. |
521 | * We currently only support VR11. | 520 | * We currently only support VR11. |
522 | */ | 521 | */ |
523 | static long pmbus_reg2data_vid(struct pmbus_data *data, | 522 | static long pmbus_reg2data_vid(struct pmbus_data *data, |
524 | struct pmbus_sensor *sensor) | 523 | struct pmbus_sensor *sensor) |
525 | { | 524 | { |
526 | long val = sensor->data; | 525 | long val = sensor->data; |
527 | 526 | ||
528 | if (val < 0x02 || val > 0xb2) | 527 | if (val < 0x02 || val > 0xb2) |
529 | return 0; | 528 | return 0; |
530 | return DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); | 529 | return DIV_ROUND_CLOSEST(160000 - (val - 2) * 625, 100); |
531 | } | 530 | } |
532 | 531 | ||
533 | static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) | 532 | static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor) |
534 | { | 533 | { |
535 | long val; | 534 | long val; |
536 | 535 | ||
537 | switch (data->info->format[sensor->class]) { | 536 | switch (data->info->format[sensor->class]) { |
538 | case direct: | 537 | case direct: |
539 | val = pmbus_reg2data_direct(data, sensor); | 538 | val = pmbus_reg2data_direct(data, sensor); |
540 | break; | 539 | break; |
541 | case vid: | 540 | case vid: |
542 | val = pmbus_reg2data_vid(data, sensor); | 541 | val = pmbus_reg2data_vid(data, sensor); |
543 | break; | 542 | break; |
544 | case linear: | 543 | case linear: |
545 | default: | 544 | default: |
546 | val = pmbus_reg2data_linear(data, sensor); | 545 | val = pmbus_reg2data_linear(data, sensor); |
547 | break; | 546 | break; |
548 | } | 547 | } |
549 | return val; | 548 | return val; |
550 | } | 549 | } |
551 | 550 | ||
552 | #define MAX_MANTISSA (1023 * 1000) | 551 | #define MAX_MANTISSA (1023 * 1000) |
553 | #define MIN_MANTISSA (511 * 1000) | 552 | #define MIN_MANTISSA (511 * 1000) |
554 | 553 | ||
555 | static u16 pmbus_data2reg_linear(struct pmbus_data *data, | 554 | static u16 pmbus_data2reg_linear(struct pmbus_data *data, |
556 | enum pmbus_sensor_classes class, long val) | 555 | enum pmbus_sensor_classes class, long val) |
557 | { | 556 | { |
558 | s16 exponent = 0, mantissa; | 557 | s16 exponent = 0, mantissa; |
559 | bool negative = false; | 558 | bool negative = false; |
560 | 559 | ||
561 | /* simple case */ | 560 | /* simple case */ |
562 | if (val == 0) | 561 | if (val == 0) |
563 | return 0; | 562 | return 0; |
564 | 563 | ||
565 | if (class == PSC_VOLTAGE_OUT) { | 564 | if (class == PSC_VOLTAGE_OUT) { |
566 | /* LINEAR16 does not support negative voltages */ | 565 | /* LINEAR16 does not support negative voltages */ |
567 | if (val < 0) | 566 | if (val < 0) |
568 | return 0; | 567 | return 0; |
569 | 568 | ||
570 | /* | 569 | /* |
571 | * For a static exponents, we don't have a choice | 570 | * For a static exponents, we don't have a choice |
572 | * but to adjust the value to it. | 571 | * but to adjust the value to it. |
573 | */ | 572 | */ |
574 | if (data->exponent < 0) | 573 | if (data->exponent < 0) |
575 | val <<= -data->exponent; | 574 | val <<= -data->exponent; |
576 | else | 575 | else |
577 | val >>= data->exponent; | 576 | val >>= data->exponent; |
578 | val = DIV_ROUND_CLOSEST(val, 1000); | 577 | val = DIV_ROUND_CLOSEST(val, 1000); |
579 | return val & 0xffff; | 578 | return val & 0xffff; |
580 | } | 579 | } |
581 | 580 | ||
582 | if (val < 0) { | 581 | if (val < 0) { |
583 | negative = true; | 582 | negative = true; |
584 | val = -val; | 583 | val = -val; |
585 | } | 584 | } |
586 | 585 | ||
587 | /* Power is in uW. Convert to mW before converting. */ | 586 | /* Power is in uW. Convert to mW before converting. */ |
588 | if (class == PSC_POWER) | 587 | if (class == PSC_POWER) |
589 | val = DIV_ROUND_CLOSEST(val, 1000L); | 588 | val = DIV_ROUND_CLOSEST(val, 1000L); |
590 | 589 | ||
591 | /* | 590 | /* |
592 | * For simplicity, convert fan data to milli-units | 591 | * For simplicity, convert fan data to milli-units |
593 | * before calculating the exponent. | 592 | * before calculating the exponent. |
594 | */ | 593 | */ |
595 | if (class == PSC_FAN) | 594 | if (class == PSC_FAN) |
596 | val = val * 1000; | 595 | val = val * 1000; |
597 | 596 | ||
598 | /* Reduce large mantissa until it fits into 10 bit */ | 597 | /* Reduce large mantissa until it fits into 10 bit */ |
599 | while (val >= MAX_MANTISSA && exponent < 15) { | 598 | while (val >= MAX_MANTISSA && exponent < 15) { |
600 | exponent++; | 599 | exponent++; |
601 | val >>= 1; | 600 | val >>= 1; |
602 | } | 601 | } |
603 | /* Increase small mantissa to improve precision */ | 602 | /* Increase small mantissa to improve precision */ |
604 | while (val < MIN_MANTISSA && exponent > -15) { | 603 | while (val < MIN_MANTISSA && exponent > -15) { |
605 | exponent--; | 604 | exponent--; |
606 | val <<= 1; | 605 | val <<= 1; |
607 | } | 606 | } |
608 | 607 | ||
609 | /* Convert mantissa from milli-units to units */ | 608 | /* Convert mantissa from milli-units to units */ |
610 | mantissa = DIV_ROUND_CLOSEST(val, 1000); | 609 | mantissa = DIV_ROUND_CLOSEST(val, 1000); |
611 | 610 | ||
612 | /* Ensure that resulting number is within range */ | 611 | /* Ensure that resulting number is within range */ |
613 | if (mantissa > 0x3ff) | 612 | if (mantissa > 0x3ff) |
614 | mantissa = 0x3ff; | 613 | mantissa = 0x3ff; |
615 | 614 | ||
616 | /* restore sign */ | 615 | /* restore sign */ |
617 | if (negative) | 616 | if (negative) |
618 | mantissa = -mantissa; | 617 | mantissa = -mantissa; |
619 | 618 | ||
620 | /* Convert to 5 bit exponent, 11 bit mantissa */ | 619 | /* Convert to 5 bit exponent, 11 bit mantissa */ |
621 | return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); | 620 | return (mantissa & 0x7ff) | ((exponent << 11) & 0xf800); |
622 | } | 621 | } |
623 | 622 | ||
624 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, | 623 | static u16 pmbus_data2reg_direct(struct pmbus_data *data, |
625 | enum pmbus_sensor_classes class, long val) | 624 | enum pmbus_sensor_classes class, long val) |
626 | { | 625 | { |
627 | long m, b, R; | 626 | long m, b, R; |
628 | 627 | ||
629 | m = data->info->m[class]; | 628 | m = data->info->m[class]; |
630 | b = data->info->b[class]; | 629 | b = data->info->b[class]; |
631 | R = data->info->R[class]; | 630 | R = data->info->R[class]; |
632 | 631 | ||
633 | /* Power is in uW. Adjust R and b. */ | 632 | /* Power is in uW. Adjust R and b. */ |
634 | if (class == PSC_POWER) { | 633 | if (class == PSC_POWER) { |
635 | R -= 3; | 634 | R -= 3; |
636 | b *= 1000; | 635 | b *= 1000; |
637 | } | 636 | } |
638 | 637 | ||
639 | /* Calculate Y = (m * X + b) * 10^R */ | 638 | /* Calculate Y = (m * X + b) * 10^R */ |
640 | if (class != PSC_FAN) { | 639 | if (class != PSC_FAN) { |
641 | R -= 3; /* Adjust R and b for data in milli-units */ | 640 | R -= 3; /* Adjust R and b for data in milli-units */ |
642 | b *= 1000; | 641 | b *= 1000; |
643 | } | 642 | } |
644 | val = val * m + b; | 643 | val = val * m + b; |
645 | 644 | ||
646 | while (R > 0) { | 645 | while (R > 0) { |
647 | val *= 10; | 646 | val *= 10; |
648 | R--; | 647 | R--; |
649 | } | 648 | } |
650 | while (R < 0) { | 649 | while (R < 0) { |
651 | val = DIV_ROUND_CLOSEST(val, 10); | 650 | val = DIV_ROUND_CLOSEST(val, 10); |
652 | R++; | 651 | R++; |
653 | } | 652 | } |
654 | 653 | ||
655 | return val; | 654 | return val; |
656 | } | 655 | } |
657 | 656 | ||
658 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, | 657 | static u16 pmbus_data2reg_vid(struct pmbus_data *data, |
659 | enum pmbus_sensor_classes class, long val) | 658 | enum pmbus_sensor_classes class, long val) |
660 | { | 659 | { |
661 | val = SENSORS_LIMIT(val, 500, 1600); | 660 | val = SENSORS_LIMIT(val, 500, 1600); |
662 | 661 | ||
663 | return 2 + DIV_ROUND_CLOSEST((1600 - val) * 100, 625); | 662 | return 2 + DIV_ROUND_CLOSEST((1600 - val) * 100, 625); |
664 | } | 663 | } |
665 | 664 | ||
666 | static u16 pmbus_data2reg(struct pmbus_data *data, | 665 | static u16 pmbus_data2reg(struct pmbus_data *data, |
667 | enum pmbus_sensor_classes class, long val) | 666 | enum pmbus_sensor_classes class, long val) |
668 | { | 667 | { |
669 | u16 regval; | 668 | u16 regval; |
670 | 669 | ||
671 | switch (data->info->format[class]) { | 670 | switch (data->info->format[class]) { |
672 | case direct: | 671 | case direct: |
673 | regval = pmbus_data2reg_direct(data, class, val); | 672 | regval = pmbus_data2reg_direct(data, class, val); |
674 | break; | 673 | break; |
675 | case vid: | 674 | case vid: |
676 | regval = pmbus_data2reg_vid(data, class, val); | 675 | regval = pmbus_data2reg_vid(data, class, val); |
677 | break; | 676 | break; |
678 | case linear: | 677 | case linear: |
679 | default: | 678 | default: |
680 | regval = pmbus_data2reg_linear(data, class, val); | 679 | regval = pmbus_data2reg_linear(data, class, val); |
681 | break; | 680 | break; |
682 | } | 681 | } |
683 | return regval; | 682 | return regval; |
684 | } | 683 | } |
685 | 684 | ||
686 | /* | 685 | /* |
687 | * Return boolean calculated from converted data. | 686 | * Return boolean calculated from converted data. |
688 | * <index> defines a status register index and mask, and optionally | 687 | * <index> defines a status register index and mask, and optionally |
689 | * two sensor indexes. | 688 | * two sensor indexes. |
690 | * The upper half-word references the two sensors, | 689 | * The upper half-word references the two sensors, |
691 | * two sensor indices. | 690 | * two sensor indices. |
692 | * The upper half-word references the two optional sensors, | 691 | * The upper half-word references the two optional sensors, |
693 | * the lower half word references status register and mask. | 692 | * the lower half word references status register and mask. |
694 | * The function returns true if (status[reg] & mask) is true and, | 693 | * The function returns true if (status[reg] & mask) is true and, |
695 | * if specified, if v1 >= v2. | 694 | * if specified, if v1 >= v2. |
696 | * To determine if an object exceeds upper limits, specify <v, limit>. | 695 | * To determine if an object exceeds upper limits, specify <v, limit>. |
697 | * To determine if an object exceeds lower limits, specify <limit, v>. | 696 | * To determine if an object exceeds lower limits, specify <limit, v>. |
698 | * | 697 | * |
699 | * For booleans created with pmbus_add_boolean_reg(), only the lower 16 bits of | 698 | * For booleans created with pmbus_add_boolean_reg(), only the lower 16 bits of |
700 | * index are set. s1 and s2 (the sensor index values) are zero in this case. | 699 | * index are set. s1 and s2 (the sensor index values) are zero in this case. |
701 | * The function returns true if (status[reg] & mask) is true. | 700 | * The function returns true if (status[reg] & mask) is true. |
702 | * | 701 | * |
703 | * If the boolean was created with pmbus_add_boolean_cmp(), a comparison against | 702 | * If the boolean was created with pmbus_add_boolean_cmp(), a comparison against |
704 | * a specified limit has to be performed to determine the boolean result. | 703 | * a specified limit has to be performed to determine the boolean result. |
705 | * In this case, the function returns true if v1 >= v2 (where v1 and v2 are | 704 | * In this case, the function returns true if v1 >= v2 (where v1 and v2 are |
706 | * sensor values referenced by sensor indices s1 and s2). | 705 | * sensor values referenced by sensor indices s1 and s2). |
707 | * | 706 | * |
708 | * To determine if an object exceeds upper limits, specify <s1,s2> = <v,limit>. | 707 | * To determine if an object exceeds upper limits, specify <s1,s2> = <v,limit>. |
709 | * To determine if an object exceeds lower limits, specify <s1,s2> = <limit,v>. | 708 | * To determine if an object exceeds lower limits, specify <s1,s2> = <limit,v>. |
710 | * | 709 | * |
711 | * If a negative value is stored in any of the referenced registers, this value | 710 | * If a negative value is stored in any of the referenced registers, this value |
712 | * reflects an error code which will be returned. | 711 | * reflects an error code which will be returned. |
713 | */ | 712 | */ |
714 | static int pmbus_get_boolean(struct pmbus_data *data, int index) | 713 | static int pmbus_get_boolean(struct pmbus_data *data, int index) |
715 | { | 714 | { |
716 | u8 s1 = (index >> 24) & 0xff; | 715 | u8 s1 = (index >> 24) & 0xff; |
717 | u8 s2 = (index >> 16) & 0xff; | 716 | u8 s2 = (index >> 16) & 0xff; |
718 | u8 reg = (index >> 8) & 0xff; | 717 | u8 reg = (index >> 8) & 0xff; |
719 | u8 mask = index & 0xff; | 718 | u8 mask = index & 0xff; |
720 | int ret, status; | 719 | int ret, status; |
721 | u8 regval; | 720 | u8 regval; |
722 | 721 | ||
723 | status = data->status[reg]; | 722 | status = data->status[reg]; |
724 | if (status < 0) | 723 | if (status < 0) |
725 | return status; | 724 | return status; |
726 | 725 | ||
727 | regval = status & mask; | 726 | regval = status & mask; |
728 | if (!s1 && !s2) | 727 | if (!s1 && !s2) |
729 | ret = !!regval; | 728 | ret = !!regval; |
730 | else { | 729 | else { |
731 | long v1, v2; | 730 | long v1, v2; |
732 | struct pmbus_sensor *sensor1, *sensor2; | 731 | struct pmbus_sensor *sensor1, *sensor2; |
733 | 732 | ||
734 | sensor1 = &data->sensors[s1]; | 733 | sensor1 = &data->sensors[s1]; |
735 | if (sensor1->data < 0) | 734 | if (sensor1->data < 0) |
736 | return sensor1->data; | 735 | return sensor1->data; |
737 | sensor2 = &data->sensors[s2]; | 736 | sensor2 = &data->sensors[s2]; |
738 | if (sensor2->data < 0) | 737 | if (sensor2->data < 0) |
739 | return sensor2->data; | 738 | return sensor2->data; |
740 | 739 | ||
741 | v1 = pmbus_reg2data(data, sensor1); | 740 | v1 = pmbus_reg2data(data, sensor1); |
742 | v2 = pmbus_reg2data(data, sensor2); | 741 | v2 = pmbus_reg2data(data, sensor2); |
743 | ret = !!(regval && v1 >= v2); | 742 | ret = !!(regval && v1 >= v2); |
744 | } | 743 | } |
745 | return ret; | 744 | return ret; |
746 | } | 745 | } |
747 | 746 | ||
748 | static ssize_t pmbus_show_boolean(struct device *dev, | 747 | static ssize_t pmbus_show_boolean(struct device *dev, |
749 | struct device_attribute *da, char *buf) | 748 | struct device_attribute *da, char *buf) |
750 | { | 749 | { |
751 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 750 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
752 | struct pmbus_data *data = pmbus_update_device(dev); | 751 | struct pmbus_data *data = pmbus_update_device(dev); |
753 | int val; | 752 | int val; |
754 | 753 | ||
755 | val = pmbus_get_boolean(data, attr->index); | 754 | val = pmbus_get_boolean(data, attr->index); |
756 | if (val < 0) | 755 | if (val < 0) |
757 | return val; | 756 | return val; |
758 | return snprintf(buf, PAGE_SIZE, "%d\n", val); | 757 | return snprintf(buf, PAGE_SIZE, "%d\n", val); |
759 | } | 758 | } |
760 | 759 | ||
761 | static ssize_t pmbus_show_sensor(struct device *dev, | 760 | static ssize_t pmbus_show_sensor(struct device *dev, |
762 | struct device_attribute *da, char *buf) | 761 | struct device_attribute *da, char *buf) |
763 | { | 762 | { |
764 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 763 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
765 | struct pmbus_data *data = pmbus_update_device(dev); | 764 | struct pmbus_data *data = pmbus_update_device(dev); |
766 | struct pmbus_sensor *sensor; | 765 | struct pmbus_sensor *sensor; |
767 | 766 | ||
768 | sensor = &data->sensors[attr->index]; | 767 | sensor = &data->sensors[attr->index]; |
769 | if (sensor->data < 0) | 768 | if (sensor->data < 0) |
770 | return sensor->data; | 769 | return sensor->data; |
771 | 770 | ||
772 | return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor)); | 771 | return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor)); |
773 | } | 772 | } |
774 | 773 | ||
775 | static ssize_t pmbus_set_sensor(struct device *dev, | 774 | static ssize_t pmbus_set_sensor(struct device *dev, |
776 | struct device_attribute *devattr, | 775 | struct device_attribute *devattr, |
777 | const char *buf, size_t count) | 776 | const char *buf, size_t count) |
778 | { | 777 | { |
779 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | 778 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); |
780 | struct i2c_client *client = to_i2c_client(dev); | 779 | struct i2c_client *client = to_i2c_client(dev); |
781 | struct pmbus_data *data = i2c_get_clientdata(client); | 780 | struct pmbus_data *data = i2c_get_clientdata(client); |
782 | struct pmbus_sensor *sensor = &data->sensors[attr->index]; | 781 | struct pmbus_sensor *sensor = &data->sensors[attr->index]; |
783 | ssize_t rv = count; | 782 | ssize_t rv = count; |
784 | long val = 0; | 783 | long val = 0; |
785 | int ret; | 784 | int ret; |
786 | u16 regval; | 785 | u16 regval; |
787 | 786 | ||
788 | if (kstrtol(buf, 10, &val) < 0) | 787 | if (kstrtol(buf, 10, &val) < 0) |
789 | return -EINVAL; | 788 | return -EINVAL; |
790 | 789 | ||
791 | mutex_lock(&data->update_lock); | 790 | mutex_lock(&data->update_lock); |
792 | regval = pmbus_data2reg(data, sensor->class, val); | 791 | regval = pmbus_data2reg(data, sensor->class, val); |
793 | ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); | 792 | ret = _pmbus_write_word_data(client, sensor->page, sensor->reg, regval); |
794 | if (ret < 0) | 793 | if (ret < 0) |
795 | rv = ret; | 794 | rv = ret; |
796 | else | 795 | else |
797 | data->sensors[attr->index].data = regval; | 796 | data->sensors[attr->index].data = regval; |
798 | mutex_unlock(&data->update_lock); | 797 | mutex_unlock(&data->update_lock); |
799 | return rv; | 798 | return rv; |
800 | } | 799 | } |
801 | 800 | ||
802 | static ssize_t pmbus_show_label(struct device *dev, | 801 | static ssize_t pmbus_show_label(struct device *dev, |
803 | struct device_attribute *da, char *buf) | 802 | struct device_attribute *da, char *buf) |
804 | { | 803 | { |
805 | struct i2c_client *client = to_i2c_client(dev); | 804 | struct i2c_client *client = to_i2c_client(dev); |
806 | struct pmbus_data *data = i2c_get_clientdata(client); | 805 | struct pmbus_data *data = i2c_get_clientdata(client); |
807 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 806 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
808 | 807 | ||
809 | return snprintf(buf, PAGE_SIZE, "%s\n", | 808 | return snprintf(buf, PAGE_SIZE, "%s\n", |
810 | data->labels[attr->index].label); | 809 | data->labels[attr->index].label); |
811 | } | 810 | } |
812 | 811 | ||
813 | #define PMBUS_ADD_ATTR(data, _name, _idx, _mode, _type, _show, _set) \ | 812 | #define PMBUS_ADD_ATTR(data, _name, _idx, _mode, _type, _show, _set) \ |
814 | do { \ | 813 | do { \ |
815 | struct sensor_device_attribute *a \ | 814 | struct sensor_device_attribute *a \ |
816 | = &data->_type##s[data->num_##_type##s].attribute; \ | 815 | = &data->_type##s[data->num_##_type##s].attribute; \ |
817 | BUG_ON(data->num_attributes >= data->max_attributes); \ | 816 | BUG_ON(data->num_attributes >= data->max_attributes); \ |
818 | sysfs_attr_init(&a->dev_attr.attr); \ | 817 | sysfs_attr_init(&a->dev_attr.attr); \ |
819 | a->dev_attr.attr.name = _name; \ | 818 | a->dev_attr.attr.name = _name; \ |
820 | a->dev_attr.attr.mode = _mode; \ | 819 | a->dev_attr.attr.mode = _mode; \ |
821 | a->dev_attr.show = _show; \ | 820 | a->dev_attr.show = _show; \ |
822 | a->dev_attr.store = _set; \ | 821 | a->dev_attr.store = _set; \ |
823 | a->index = _idx; \ | 822 | a->index = _idx; \ |
824 | data->attributes[data->num_attributes] = &a->dev_attr.attr; \ | 823 | data->attributes[data->num_attributes] = &a->dev_attr.attr; \ |
825 | data->num_attributes++; \ | 824 | data->num_attributes++; \ |
826 | } while (0) | 825 | } while (0) |
827 | 826 | ||
828 | #define PMBUS_ADD_GET_ATTR(data, _name, _type, _idx) \ | 827 | #define PMBUS_ADD_GET_ATTR(data, _name, _type, _idx) \ |
829 | PMBUS_ADD_ATTR(data, _name, _idx, S_IRUGO, _type, \ | 828 | PMBUS_ADD_ATTR(data, _name, _idx, S_IRUGO, _type, \ |
830 | pmbus_show_##_type, NULL) | 829 | pmbus_show_##_type, NULL) |
831 | 830 | ||
832 | #define PMBUS_ADD_SET_ATTR(data, _name, _type, _idx) \ | 831 | #define PMBUS_ADD_SET_ATTR(data, _name, _type, _idx) \ |
833 | PMBUS_ADD_ATTR(data, _name, _idx, S_IWUSR | S_IRUGO, _type, \ | 832 | PMBUS_ADD_ATTR(data, _name, _idx, S_IWUSR | S_IRUGO, _type, \ |
834 | pmbus_show_##_type, pmbus_set_##_type) | 833 | pmbus_show_##_type, pmbus_set_##_type) |
835 | 834 | ||
836 | static void pmbus_add_boolean(struct pmbus_data *data, | 835 | static void pmbus_add_boolean(struct pmbus_data *data, |
837 | const char *name, const char *type, int seq, | 836 | const char *name, const char *type, int seq, |
838 | int idx) | 837 | int idx) |
839 | { | 838 | { |
840 | struct pmbus_boolean *boolean; | 839 | struct pmbus_boolean *boolean; |
841 | 840 | ||
842 | BUG_ON(data->num_booleans >= data->max_booleans); | 841 | BUG_ON(data->num_booleans >= data->max_booleans); |
843 | 842 | ||
844 | boolean = &data->booleans[data->num_booleans]; | 843 | boolean = &data->booleans[data->num_booleans]; |
845 | 844 | ||
846 | snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s", | 845 | snprintf(boolean->name, sizeof(boolean->name), "%s%d_%s", |
847 | name, seq, type); | 846 | name, seq, type); |
848 | PMBUS_ADD_GET_ATTR(data, boolean->name, boolean, idx); | 847 | PMBUS_ADD_GET_ATTR(data, boolean->name, boolean, idx); |
849 | data->num_booleans++; | 848 | data->num_booleans++; |
850 | } | 849 | } |
851 | 850 | ||
852 | static void pmbus_add_boolean_reg(struct pmbus_data *data, | 851 | static void pmbus_add_boolean_reg(struct pmbus_data *data, |
853 | const char *name, const char *type, | 852 | const char *name, const char *type, |
854 | int seq, int reg, int bit) | 853 | int seq, int reg, int bit) |
855 | { | 854 | { |
856 | pmbus_add_boolean(data, name, type, seq, (reg << 8) | bit); | 855 | pmbus_add_boolean(data, name, type, seq, (reg << 8) | bit); |
857 | } | 856 | } |
858 | 857 | ||
859 | static void pmbus_add_boolean_cmp(struct pmbus_data *data, | 858 | static void pmbus_add_boolean_cmp(struct pmbus_data *data, |
860 | const char *name, const char *type, | 859 | const char *name, const char *type, |
861 | int seq, int i1, int i2, int reg, int mask) | 860 | int seq, int i1, int i2, int reg, int mask) |
862 | { | 861 | { |
863 | pmbus_add_boolean(data, name, type, seq, | 862 | pmbus_add_boolean(data, name, type, seq, |
864 | (i1 << 24) | (i2 << 16) | (reg << 8) | mask); | 863 | (i1 << 24) | (i2 << 16) | (reg << 8) | mask); |
865 | } | 864 | } |
866 | 865 | ||
867 | static void pmbus_add_sensor(struct pmbus_data *data, | 866 | static void pmbus_add_sensor(struct pmbus_data *data, |
868 | const char *name, const char *type, int seq, | 867 | const char *name, const char *type, int seq, |
869 | int page, int reg, enum pmbus_sensor_classes class, | 868 | int page, int reg, enum pmbus_sensor_classes class, |
870 | bool update, bool readonly) | 869 | bool update, bool readonly) |
871 | { | 870 | { |
872 | struct pmbus_sensor *sensor; | 871 | struct pmbus_sensor *sensor; |
873 | 872 | ||
874 | BUG_ON(data->num_sensors >= data->max_sensors); | 873 | BUG_ON(data->num_sensors >= data->max_sensors); |
875 | 874 | ||
876 | sensor = &data->sensors[data->num_sensors]; | 875 | sensor = &data->sensors[data->num_sensors]; |
877 | snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", | 876 | snprintf(sensor->name, sizeof(sensor->name), "%s%d_%s", |
878 | name, seq, type); | 877 | name, seq, type); |
879 | sensor->page = page; | 878 | sensor->page = page; |
880 | sensor->reg = reg; | 879 | sensor->reg = reg; |
881 | sensor->class = class; | 880 | sensor->class = class; |
882 | sensor->update = update; | 881 | sensor->update = update; |
883 | if (readonly) | 882 | if (readonly) |
884 | PMBUS_ADD_GET_ATTR(data, sensor->name, sensor, | 883 | PMBUS_ADD_GET_ATTR(data, sensor->name, sensor, |
885 | data->num_sensors); | 884 | data->num_sensors); |
886 | else | 885 | else |
887 | PMBUS_ADD_SET_ATTR(data, sensor->name, sensor, | 886 | PMBUS_ADD_SET_ATTR(data, sensor->name, sensor, |
888 | data->num_sensors); | 887 | data->num_sensors); |
889 | data->num_sensors++; | 888 | data->num_sensors++; |
890 | } | 889 | } |
891 | 890 | ||
892 | static void pmbus_add_label(struct pmbus_data *data, | 891 | static void pmbus_add_label(struct pmbus_data *data, |
893 | const char *name, int seq, | 892 | const char *name, int seq, |
894 | const char *lstring, int index) | 893 | const char *lstring, int index) |
895 | { | 894 | { |
896 | struct pmbus_label *label; | 895 | struct pmbus_label *label; |
897 | 896 | ||
898 | BUG_ON(data->num_labels >= data->max_labels); | 897 | BUG_ON(data->num_labels >= data->max_labels); |
899 | 898 | ||
900 | label = &data->labels[data->num_labels]; | 899 | label = &data->labels[data->num_labels]; |
901 | snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); | 900 | snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); |
902 | if (!index) | 901 | if (!index) |
903 | strncpy(label->label, lstring, sizeof(label->label) - 1); | 902 | strncpy(label->label, lstring, sizeof(label->label) - 1); |
904 | else | 903 | else |
905 | snprintf(label->label, sizeof(label->label), "%s%d", lstring, | 904 | snprintf(label->label, sizeof(label->label), "%s%d", lstring, |
906 | index); | 905 | index); |
907 | 906 | ||
908 | PMBUS_ADD_GET_ATTR(data, label->name, label, data->num_labels); | 907 | PMBUS_ADD_GET_ATTR(data, label->name, label, data->num_labels); |
909 | data->num_labels++; | 908 | data->num_labels++; |
910 | } | 909 | } |
911 | 910 | ||
912 | /* | 911 | /* |
913 | * Determine maximum number of sensors, booleans, and labels. | 912 | * Determine maximum number of sensors, booleans, and labels. |
914 | * To keep things simple, only make a rough high estimate. | 913 | * To keep things simple, only make a rough high estimate. |
915 | */ | 914 | */ |
916 | static void pmbus_find_max_attr(struct i2c_client *client, | 915 | static void pmbus_find_max_attr(struct i2c_client *client, |
917 | struct pmbus_data *data) | 916 | struct pmbus_data *data) |
918 | { | 917 | { |
919 | const struct pmbus_driver_info *info = data->info; | 918 | const struct pmbus_driver_info *info = data->info; |
920 | int page, max_sensors, max_booleans, max_labels; | 919 | int page, max_sensors, max_booleans, max_labels; |
921 | 920 | ||
922 | max_sensors = PMBUS_MAX_INPUT_SENSORS; | 921 | max_sensors = PMBUS_MAX_INPUT_SENSORS; |
923 | max_booleans = PMBUS_MAX_INPUT_BOOLEANS; | 922 | max_booleans = PMBUS_MAX_INPUT_BOOLEANS; |
924 | max_labels = PMBUS_MAX_INPUT_LABELS; | 923 | max_labels = PMBUS_MAX_INPUT_LABELS; |
925 | 924 | ||
926 | for (page = 0; page < info->pages; page++) { | 925 | for (page = 0; page < info->pages; page++) { |
927 | if (info->func[page] & PMBUS_HAVE_VOUT) { | 926 | if (info->func[page] & PMBUS_HAVE_VOUT) { |
928 | max_sensors += PMBUS_VOUT_SENSORS_PER_PAGE; | 927 | max_sensors += PMBUS_VOUT_SENSORS_PER_PAGE; |
929 | max_booleans += PMBUS_VOUT_BOOLEANS_PER_PAGE; | 928 | max_booleans += PMBUS_VOUT_BOOLEANS_PER_PAGE; |
930 | max_labels++; | 929 | max_labels++; |
931 | } | 930 | } |
932 | if (info->func[page] & PMBUS_HAVE_IOUT) { | 931 | if (info->func[page] & PMBUS_HAVE_IOUT) { |
933 | max_sensors += PMBUS_IOUT_SENSORS_PER_PAGE; | 932 | max_sensors += PMBUS_IOUT_SENSORS_PER_PAGE; |
934 | max_booleans += PMBUS_IOUT_BOOLEANS_PER_PAGE; | 933 | max_booleans += PMBUS_IOUT_BOOLEANS_PER_PAGE; |
935 | max_labels++; | 934 | max_labels++; |
936 | } | 935 | } |
937 | if (info->func[page] & PMBUS_HAVE_POUT) { | 936 | if (info->func[page] & PMBUS_HAVE_POUT) { |
938 | max_sensors += PMBUS_POUT_SENSORS_PER_PAGE; | 937 | max_sensors += PMBUS_POUT_SENSORS_PER_PAGE; |
939 | max_booleans += PMBUS_POUT_BOOLEANS_PER_PAGE; | 938 | max_booleans += PMBUS_POUT_BOOLEANS_PER_PAGE; |
940 | max_labels++; | 939 | max_labels++; |
941 | } | 940 | } |
942 | if (info->func[page] & PMBUS_HAVE_FAN12) { | 941 | if (info->func[page] & PMBUS_HAVE_FAN12) { |
943 | max_sensors += 2 * PMBUS_MAX_SENSORS_PER_FAN; | 942 | max_sensors += 2 * PMBUS_MAX_SENSORS_PER_FAN; |
944 | max_booleans += 2 * PMBUS_MAX_BOOLEANS_PER_FAN; | 943 | max_booleans += 2 * PMBUS_MAX_BOOLEANS_PER_FAN; |
945 | } | 944 | } |
946 | if (info->func[page] & PMBUS_HAVE_FAN34) { | 945 | if (info->func[page] & PMBUS_HAVE_FAN34) { |
947 | max_sensors += 2 * PMBUS_MAX_SENSORS_PER_FAN; | 946 | max_sensors += 2 * PMBUS_MAX_SENSORS_PER_FAN; |
948 | max_booleans += 2 * PMBUS_MAX_BOOLEANS_PER_FAN; | 947 | max_booleans += 2 * PMBUS_MAX_BOOLEANS_PER_FAN; |
949 | } | 948 | } |
950 | if (info->func[page] & PMBUS_HAVE_TEMP) { | 949 | if (info->func[page] & PMBUS_HAVE_TEMP) { |
951 | max_sensors += PMBUS_MAX_SENSORS_PER_TEMP; | 950 | max_sensors += PMBUS_MAX_SENSORS_PER_TEMP; |
952 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; | 951 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; |
953 | } | 952 | } |
954 | if (info->func[page] & PMBUS_HAVE_TEMP2) { | 953 | if (info->func[page] & PMBUS_HAVE_TEMP2) { |
955 | max_sensors += PMBUS_MAX_SENSORS_PER_TEMP; | 954 | max_sensors += PMBUS_MAX_SENSORS_PER_TEMP; |
956 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; | 955 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; |
957 | } | 956 | } |
958 | if (info->func[page] & PMBUS_HAVE_TEMP3) { | 957 | if (info->func[page] & PMBUS_HAVE_TEMP3) { |
959 | max_sensors += PMBUS_MAX_SENSORS_PER_TEMP; | 958 | max_sensors += PMBUS_MAX_SENSORS_PER_TEMP; |
960 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; | 959 | max_booleans += PMBUS_MAX_BOOLEANS_PER_TEMP; |
961 | } | 960 | } |
962 | } | 961 | } |
963 | data->max_sensors = max_sensors; | 962 | data->max_sensors = max_sensors; |
964 | data->max_booleans = max_booleans; | 963 | data->max_booleans = max_booleans; |
965 | data->max_labels = max_labels; | 964 | data->max_labels = max_labels; |
966 | data->max_attributes = max_sensors + max_booleans + max_labels; | 965 | data->max_attributes = max_sensors + max_booleans + max_labels; |
967 | } | 966 | } |
968 | 967 | ||
969 | /* | 968 | /* |
970 | * Search for attributes. Allocate sensors, booleans, and labels as needed. | 969 | * Search for attributes. Allocate sensors, booleans, and labels as needed. |
971 | */ | 970 | */ |
972 | 971 | ||
973 | /* | 972 | /* |
974 | * The pmbus_limit_attr structure describes a single limit attribute | 973 | * The pmbus_limit_attr structure describes a single limit attribute |
975 | * and its associated alarm attribute. | 974 | * and its associated alarm attribute. |
976 | */ | 975 | */ |
977 | struct pmbus_limit_attr { | 976 | struct pmbus_limit_attr { |
978 | u16 reg; /* Limit register */ | 977 | u16 reg; /* Limit register */ |
979 | bool update; /* True if register needs updates */ | 978 | bool update; /* True if register needs updates */ |
980 | bool low; /* True if low limit; for limits with compare | 979 | bool low; /* True if low limit; for limits with compare |
981 | functions only */ | 980 | functions only */ |
982 | const char *attr; /* Attribute name */ | 981 | const char *attr; /* Attribute name */ |
983 | const char *alarm; /* Alarm attribute name */ | 982 | const char *alarm; /* Alarm attribute name */ |
984 | u32 sbit; /* Alarm attribute status bit */ | 983 | u32 sbit; /* Alarm attribute status bit */ |
985 | }; | 984 | }; |
986 | 985 | ||
987 | /* | 986 | /* |
988 | * The pmbus_sensor_attr structure describes one sensor attribute. This | 987 | * The pmbus_sensor_attr structure describes one sensor attribute. This |
989 | * description includes a reference to the associated limit attributes. | 988 | * description includes a reference to the associated limit attributes. |
990 | */ | 989 | */ |
991 | struct pmbus_sensor_attr { | 990 | struct pmbus_sensor_attr { |
992 | u8 reg; /* sensor register */ | 991 | u8 reg; /* sensor register */ |
993 | enum pmbus_sensor_classes class;/* sensor class */ | 992 | enum pmbus_sensor_classes class;/* sensor class */ |
994 | const char *label; /* sensor label */ | 993 | const char *label; /* sensor label */ |
995 | bool paged; /* true if paged sensor */ | 994 | bool paged; /* true if paged sensor */ |
996 | bool update; /* true if update needed */ | 995 | bool update; /* true if update needed */ |
997 | bool compare; /* true if compare function needed */ | 996 | bool compare; /* true if compare function needed */ |
998 | u32 func; /* sensor mask */ | 997 | u32 func; /* sensor mask */ |
999 | u32 sfunc; /* sensor status mask */ | 998 | u32 sfunc; /* sensor status mask */ |
1000 | int sbase; /* status base register */ | 999 | int sbase; /* status base register */ |
1001 | u32 gbit; /* generic status bit */ | 1000 | u32 gbit; /* generic status bit */ |
1002 | const struct pmbus_limit_attr *limit;/* limit registers */ | 1001 | const struct pmbus_limit_attr *limit;/* limit registers */ |
1003 | int nlimit; /* # of limit registers */ | 1002 | int nlimit; /* # of limit registers */ |
1004 | }; | 1003 | }; |
1005 | 1004 | ||
1006 | /* | 1005 | /* |
1007 | * Add a set of limit attributes and, if supported, the associated | 1006 | * Add a set of limit attributes and, if supported, the associated |
1008 | * alarm attributes. | 1007 | * alarm attributes. |
1009 | */ | 1008 | */ |
1010 | static bool pmbus_add_limit_attrs(struct i2c_client *client, | 1009 | static bool pmbus_add_limit_attrs(struct i2c_client *client, |
1011 | struct pmbus_data *data, | 1010 | struct pmbus_data *data, |
1012 | const struct pmbus_driver_info *info, | 1011 | const struct pmbus_driver_info *info, |
1013 | const char *name, int index, int page, | 1012 | const char *name, int index, int page, |
1014 | int cbase, | 1013 | int cbase, |
1015 | const struct pmbus_sensor_attr *attr) | 1014 | const struct pmbus_sensor_attr *attr) |
1016 | { | 1015 | { |
1017 | const struct pmbus_limit_attr *l = attr->limit; | 1016 | const struct pmbus_limit_attr *l = attr->limit; |
1018 | int nlimit = attr->nlimit; | 1017 | int nlimit = attr->nlimit; |
1019 | bool have_alarm = false; | 1018 | bool have_alarm = false; |
1020 | int i, cindex; | 1019 | int i, cindex; |
1021 | 1020 | ||
1022 | for (i = 0; i < nlimit; i++) { | 1021 | for (i = 0; i < nlimit; i++) { |
1023 | if (pmbus_check_word_register(client, page, l->reg)) { | 1022 | if (pmbus_check_word_register(client, page, l->reg)) { |
1024 | cindex = data->num_sensors; | 1023 | cindex = data->num_sensors; |
1025 | pmbus_add_sensor(data, name, l->attr, index, page, | 1024 | pmbus_add_sensor(data, name, l->attr, index, page, |
1026 | l->reg, attr->class, | 1025 | l->reg, attr->class, |
1027 | attr->update || l->update, | 1026 | attr->update || l->update, |
1028 | false); | 1027 | false); |
1029 | if (l->sbit && (info->func[page] & attr->sfunc)) { | 1028 | if (l->sbit && (info->func[page] & attr->sfunc)) { |
1030 | if (attr->compare) { | 1029 | if (attr->compare) { |
1031 | pmbus_add_boolean_cmp(data, name, | 1030 | pmbus_add_boolean_cmp(data, name, |
1032 | l->alarm, index, | 1031 | l->alarm, index, |
1033 | l->low ? cindex : cbase, | 1032 | l->low ? cindex : cbase, |
1034 | l->low ? cbase : cindex, | 1033 | l->low ? cbase : cindex, |
1035 | attr->sbase + page, l->sbit); | 1034 | attr->sbase + page, l->sbit); |
1036 | } else { | 1035 | } else { |
1037 | pmbus_add_boolean_reg(data, name, | 1036 | pmbus_add_boolean_reg(data, name, |
1038 | l->alarm, index, | 1037 | l->alarm, index, |
1039 | attr->sbase + page, l->sbit); | 1038 | attr->sbase + page, l->sbit); |
1040 | } | 1039 | } |
1041 | have_alarm = true; | 1040 | have_alarm = true; |
1042 | } | 1041 | } |
1043 | } | 1042 | } |
1044 | l++; | 1043 | l++; |
1045 | } | 1044 | } |
1046 | return have_alarm; | 1045 | return have_alarm; |
1047 | } | 1046 | } |
1048 | 1047 | ||
1049 | static void pmbus_add_sensor_attrs_one(struct i2c_client *client, | 1048 | static void pmbus_add_sensor_attrs_one(struct i2c_client *client, |
1050 | struct pmbus_data *data, | 1049 | struct pmbus_data *data, |
1051 | const struct pmbus_driver_info *info, | 1050 | const struct pmbus_driver_info *info, |
1052 | const char *name, | 1051 | const char *name, |
1053 | int index, int page, | 1052 | int index, int page, |
1054 | const struct pmbus_sensor_attr *attr) | 1053 | const struct pmbus_sensor_attr *attr) |
1055 | { | 1054 | { |
1056 | bool have_alarm; | 1055 | bool have_alarm; |
1057 | int cbase = data->num_sensors; | 1056 | int cbase = data->num_sensors; |
1058 | 1057 | ||
1059 | if (attr->label) | 1058 | if (attr->label) |
1060 | pmbus_add_label(data, name, index, attr->label, | 1059 | pmbus_add_label(data, name, index, attr->label, |
1061 | attr->paged ? page + 1 : 0); | 1060 | attr->paged ? page + 1 : 0); |
1062 | pmbus_add_sensor(data, name, "input", index, page, attr->reg, | 1061 | pmbus_add_sensor(data, name, "input", index, page, attr->reg, |
1063 | attr->class, true, true); | 1062 | attr->class, true, true); |
1064 | if (attr->sfunc) { | 1063 | if (attr->sfunc) { |
1065 | have_alarm = pmbus_add_limit_attrs(client, data, info, name, | 1064 | have_alarm = pmbus_add_limit_attrs(client, data, info, name, |
1066 | index, page, cbase, attr); | 1065 | index, page, cbase, attr); |
1067 | /* | 1066 | /* |
1068 | * Add generic alarm attribute only if there are no individual | 1067 | * Add generic alarm attribute only if there are no individual |
1069 | * alarm attributes, if there is a global alarm bit, and if | 1068 | * alarm attributes, if there is a global alarm bit, and if |
1070 | * the generic status register for this page is accessible. | 1069 | * the generic status register for this page is accessible. |
1071 | */ | 1070 | */ |
1072 | if (!have_alarm && attr->gbit && | 1071 | if (!have_alarm && attr->gbit && |
1073 | pmbus_check_byte_register(client, page, PMBUS_STATUS_BYTE)) | 1072 | pmbus_check_byte_register(client, page, PMBUS_STATUS_BYTE)) |
1074 | pmbus_add_boolean_reg(data, name, "alarm", index, | 1073 | pmbus_add_boolean_reg(data, name, "alarm", index, |
1075 | PB_STATUS_BASE + page, | 1074 | PB_STATUS_BASE + page, |
1076 | attr->gbit); | 1075 | attr->gbit); |
1077 | } | 1076 | } |
1078 | } | 1077 | } |
1079 | 1078 | ||
1080 | static void pmbus_add_sensor_attrs(struct i2c_client *client, | 1079 | static void pmbus_add_sensor_attrs(struct i2c_client *client, |
1081 | struct pmbus_data *data, | 1080 | struct pmbus_data *data, |
1082 | const char *name, | 1081 | const char *name, |
1083 | const struct pmbus_sensor_attr *attrs, | 1082 | const struct pmbus_sensor_attr *attrs, |
1084 | int nattrs) | 1083 | int nattrs) |
1085 | { | 1084 | { |
1086 | const struct pmbus_driver_info *info = data->info; | 1085 | const struct pmbus_driver_info *info = data->info; |
1087 | int index, i; | 1086 | int index, i; |
1088 | 1087 | ||
1089 | index = 1; | 1088 | index = 1; |
1090 | for (i = 0; i < nattrs; i++) { | 1089 | for (i = 0; i < nattrs; i++) { |
1091 | int page, pages; | 1090 | int page, pages; |
1092 | 1091 | ||
1093 | pages = attrs->paged ? info->pages : 1; | 1092 | pages = attrs->paged ? info->pages : 1; |
1094 | for (page = 0; page < pages; page++) { | 1093 | for (page = 0; page < pages; page++) { |
1095 | if (!(info->func[page] & attrs->func)) | 1094 | if (!(info->func[page] & attrs->func)) |
1096 | continue; | 1095 | continue; |
1097 | pmbus_add_sensor_attrs_one(client, data, info, name, | 1096 | pmbus_add_sensor_attrs_one(client, data, info, name, |
1098 | index, page, attrs); | 1097 | index, page, attrs); |
1099 | index++; | 1098 | index++; |
1100 | } | 1099 | } |
1101 | attrs++; | 1100 | attrs++; |
1102 | } | 1101 | } |
1103 | } | 1102 | } |
1104 | 1103 | ||
1105 | static const struct pmbus_limit_attr vin_limit_attrs[] = { | 1104 | static const struct pmbus_limit_attr vin_limit_attrs[] = { |
1106 | { | 1105 | { |
1107 | .reg = PMBUS_VIN_UV_WARN_LIMIT, | 1106 | .reg = PMBUS_VIN_UV_WARN_LIMIT, |
1108 | .attr = "min", | 1107 | .attr = "min", |
1109 | .alarm = "min_alarm", | 1108 | .alarm = "min_alarm", |
1110 | .sbit = PB_VOLTAGE_UV_WARNING, | 1109 | .sbit = PB_VOLTAGE_UV_WARNING, |
1111 | }, { | 1110 | }, { |
1112 | .reg = PMBUS_VIN_UV_FAULT_LIMIT, | 1111 | .reg = PMBUS_VIN_UV_FAULT_LIMIT, |
1113 | .attr = "lcrit", | 1112 | .attr = "lcrit", |
1114 | .alarm = "lcrit_alarm", | 1113 | .alarm = "lcrit_alarm", |
1115 | .sbit = PB_VOLTAGE_UV_FAULT, | 1114 | .sbit = PB_VOLTAGE_UV_FAULT, |
1116 | }, { | 1115 | }, { |
1117 | .reg = PMBUS_VIN_OV_WARN_LIMIT, | 1116 | .reg = PMBUS_VIN_OV_WARN_LIMIT, |
1118 | .attr = "max", | 1117 | .attr = "max", |
1119 | .alarm = "max_alarm", | 1118 | .alarm = "max_alarm", |
1120 | .sbit = PB_VOLTAGE_OV_WARNING, | 1119 | .sbit = PB_VOLTAGE_OV_WARNING, |
1121 | }, { | 1120 | }, { |
1122 | .reg = PMBUS_VIN_OV_FAULT_LIMIT, | 1121 | .reg = PMBUS_VIN_OV_FAULT_LIMIT, |
1123 | .attr = "crit", | 1122 | .attr = "crit", |
1124 | .alarm = "crit_alarm", | 1123 | .alarm = "crit_alarm", |
1125 | .sbit = PB_VOLTAGE_OV_FAULT, | 1124 | .sbit = PB_VOLTAGE_OV_FAULT, |
1126 | }, { | 1125 | }, { |
1127 | .reg = PMBUS_VIRT_READ_VIN_AVG, | 1126 | .reg = PMBUS_VIRT_READ_VIN_AVG, |
1128 | .update = true, | 1127 | .update = true, |
1129 | .attr = "average", | 1128 | .attr = "average", |
1130 | }, { | 1129 | }, { |
1131 | .reg = PMBUS_VIRT_READ_VIN_MIN, | 1130 | .reg = PMBUS_VIRT_READ_VIN_MIN, |
1132 | .update = true, | 1131 | .update = true, |
1133 | .attr = "lowest", | 1132 | .attr = "lowest", |
1134 | }, { | 1133 | }, { |
1135 | .reg = PMBUS_VIRT_READ_VIN_MAX, | 1134 | .reg = PMBUS_VIRT_READ_VIN_MAX, |
1136 | .update = true, | 1135 | .update = true, |
1137 | .attr = "highest", | 1136 | .attr = "highest", |
1138 | }, { | 1137 | }, { |
1139 | .reg = PMBUS_VIRT_RESET_VIN_HISTORY, | 1138 | .reg = PMBUS_VIRT_RESET_VIN_HISTORY, |
1140 | .attr = "reset_history", | 1139 | .attr = "reset_history", |
1141 | }, | 1140 | }, |
1142 | }; | 1141 | }; |
1143 | 1142 | ||
1144 | static const struct pmbus_limit_attr vout_limit_attrs[] = { | 1143 | static const struct pmbus_limit_attr vout_limit_attrs[] = { |
1145 | { | 1144 | { |
1146 | .reg = PMBUS_VOUT_UV_WARN_LIMIT, | 1145 | .reg = PMBUS_VOUT_UV_WARN_LIMIT, |
1147 | .attr = "min", | 1146 | .attr = "min", |
1148 | .alarm = "min_alarm", | 1147 | .alarm = "min_alarm", |
1149 | .sbit = PB_VOLTAGE_UV_WARNING, | 1148 | .sbit = PB_VOLTAGE_UV_WARNING, |
1150 | }, { | 1149 | }, { |
1151 | .reg = PMBUS_VOUT_UV_FAULT_LIMIT, | 1150 | .reg = PMBUS_VOUT_UV_FAULT_LIMIT, |
1152 | .attr = "lcrit", | 1151 | .attr = "lcrit", |
1153 | .alarm = "lcrit_alarm", | 1152 | .alarm = "lcrit_alarm", |
1154 | .sbit = PB_VOLTAGE_UV_FAULT, | 1153 | .sbit = PB_VOLTAGE_UV_FAULT, |
1155 | }, { | 1154 | }, { |
1156 | .reg = PMBUS_VOUT_OV_WARN_LIMIT, | 1155 | .reg = PMBUS_VOUT_OV_WARN_LIMIT, |
1157 | .attr = "max", | 1156 | .attr = "max", |
1158 | .alarm = "max_alarm", | 1157 | .alarm = "max_alarm", |
1159 | .sbit = PB_VOLTAGE_OV_WARNING, | 1158 | .sbit = PB_VOLTAGE_OV_WARNING, |
1160 | }, { | 1159 | }, { |
1161 | .reg = PMBUS_VOUT_OV_FAULT_LIMIT, | 1160 | .reg = PMBUS_VOUT_OV_FAULT_LIMIT, |
1162 | .attr = "crit", | 1161 | .attr = "crit", |
1163 | .alarm = "crit_alarm", | 1162 | .alarm = "crit_alarm", |
1164 | .sbit = PB_VOLTAGE_OV_FAULT, | 1163 | .sbit = PB_VOLTAGE_OV_FAULT, |
1165 | }, { | 1164 | }, { |
1166 | .reg = PMBUS_VIRT_READ_VOUT_AVG, | 1165 | .reg = PMBUS_VIRT_READ_VOUT_AVG, |
1167 | .update = true, | 1166 | .update = true, |
1168 | .attr = "average", | 1167 | .attr = "average", |
1169 | }, { | 1168 | }, { |
1170 | .reg = PMBUS_VIRT_READ_VOUT_MIN, | 1169 | .reg = PMBUS_VIRT_READ_VOUT_MIN, |
1171 | .update = true, | 1170 | .update = true, |
1172 | .attr = "lowest", | 1171 | .attr = "lowest", |
1173 | }, { | 1172 | }, { |
1174 | .reg = PMBUS_VIRT_READ_VOUT_MAX, | 1173 | .reg = PMBUS_VIRT_READ_VOUT_MAX, |
1175 | .update = true, | 1174 | .update = true, |
1176 | .attr = "highest", | 1175 | .attr = "highest", |
1177 | }, { | 1176 | }, { |
1178 | .reg = PMBUS_VIRT_RESET_VOUT_HISTORY, | 1177 | .reg = PMBUS_VIRT_RESET_VOUT_HISTORY, |
1179 | .attr = "reset_history", | 1178 | .attr = "reset_history", |
1180 | } | 1179 | } |
1181 | }; | 1180 | }; |
1182 | 1181 | ||
1183 | static const struct pmbus_sensor_attr voltage_attributes[] = { | 1182 | static const struct pmbus_sensor_attr voltage_attributes[] = { |
1184 | { | 1183 | { |
1185 | .reg = PMBUS_READ_VIN, | 1184 | .reg = PMBUS_READ_VIN, |
1186 | .class = PSC_VOLTAGE_IN, | 1185 | .class = PSC_VOLTAGE_IN, |
1187 | .label = "vin", | 1186 | .label = "vin", |
1188 | .func = PMBUS_HAVE_VIN, | 1187 | .func = PMBUS_HAVE_VIN, |
1189 | .sfunc = PMBUS_HAVE_STATUS_INPUT, | 1188 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
1190 | .sbase = PB_STATUS_INPUT_BASE, | 1189 | .sbase = PB_STATUS_INPUT_BASE, |
1191 | .gbit = PB_STATUS_VIN_UV, | 1190 | .gbit = PB_STATUS_VIN_UV, |
1192 | .limit = vin_limit_attrs, | 1191 | .limit = vin_limit_attrs, |
1193 | .nlimit = ARRAY_SIZE(vin_limit_attrs), | 1192 | .nlimit = ARRAY_SIZE(vin_limit_attrs), |
1194 | }, { | 1193 | }, { |
1195 | .reg = PMBUS_READ_VCAP, | 1194 | .reg = PMBUS_READ_VCAP, |
1196 | .class = PSC_VOLTAGE_IN, | 1195 | .class = PSC_VOLTAGE_IN, |
1197 | .label = "vcap", | 1196 | .label = "vcap", |
1198 | .func = PMBUS_HAVE_VCAP, | 1197 | .func = PMBUS_HAVE_VCAP, |
1199 | }, { | 1198 | }, { |
1200 | .reg = PMBUS_READ_VOUT, | 1199 | .reg = PMBUS_READ_VOUT, |
1201 | .class = PSC_VOLTAGE_OUT, | 1200 | .class = PSC_VOLTAGE_OUT, |
1202 | .label = "vout", | 1201 | .label = "vout", |
1203 | .paged = true, | 1202 | .paged = true, |
1204 | .func = PMBUS_HAVE_VOUT, | 1203 | .func = PMBUS_HAVE_VOUT, |
1205 | .sfunc = PMBUS_HAVE_STATUS_VOUT, | 1204 | .sfunc = PMBUS_HAVE_STATUS_VOUT, |
1206 | .sbase = PB_STATUS_VOUT_BASE, | 1205 | .sbase = PB_STATUS_VOUT_BASE, |
1207 | .gbit = PB_STATUS_VOUT_OV, | 1206 | .gbit = PB_STATUS_VOUT_OV, |
1208 | .limit = vout_limit_attrs, | 1207 | .limit = vout_limit_attrs, |
1209 | .nlimit = ARRAY_SIZE(vout_limit_attrs), | 1208 | .nlimit = ARRAY_SIZE(vout_limit_attrs), |
1210 | } | 1209 | } |
1211 | }; | 1210 | }; |
1212 | 1211 | ||
1213 | /* Current attributes */ | 1212 | /* Current attributes */ |
1214 | 1213 | ||
1215 | static const struct pmbus_limit_attr iin_limit_attrs[] = { | 1214 | static const struct pmbus_limit_attr iin_limit_attrs[] = { |
1216 | { | 1215 | { |
1217 | .reg = PMBUS_IIN_OC_WARN_LIMIT, | 1216 | .reg = PMBUS_IIN_OC_WARN_LIMIT, |
1218 | .attr = "max", | 1217 | .attr = "max", |
1219 | .alarm = "max_alarm", | 1218 | .alarm = "max_alarm", |
1220 | .sbit = PB_IIN_OC_WARNING, | 1219 | .sbit = PB_IIN_OC_WARNING, |
1221 | }, { | 1220 | }, { |
1222 | .reg = PMBUS_IIN_OC_FAULT_LIMIT, | 1221 | .reg = PMBUS_IIN_OC_FAULT_LIMIT, |
1223 | .attr = "crit", | 1222 | .attr = "crit", |
1224 | .alarm = "crit_alarm", | 1223 | .alarm = "crit_alarm", |
1225 | .sbit = PB_IIN_OC_FAULT, | 1224 | .sbit = PB_IIN_OC_FAULT, |
1226 | }, { | 1225 | }, { |
1227 | .reg = PMBUS_VIRT_READ_IIN_AVG, | 1226 | .reg = PMBUS_VIRT_READ_IIN_AVG, |
1228 | .update = true, | 1227 | .update = true, |
1229 | .attr = "average", | 1228 | .attr = "average", |
1230 | }, { | 1229 | }, { |
1231 | .reg = PMBUS_VIRT_READ_IIN_MIN, | 1230 | .reg = PMBUS_VIRT_READ_IIN_MIN, |
1232 | .update = true, | 1231 | .update = true, |
1233 | .attr = "lowest", | 1232 | .attr = "lowest", |
1234 | }, { | 1233 | }, { |
1235 | .reg = PMBUS_VIRT_READ_IIN_MAX, | 1234 | .reg = PMBUS_VIRT_READ_IIN_MAX, |
1236 | .update = true, | 1235 | .update = true, |
1237 | .attr = "highest", | 1236 | .attr = "highest", |
1238 | }, { | 1237 | }, { |
1239 | .reg = PMBUS_VIRT_RESET_IIN_HISTORY, | 1238 | .reg = PMBUS_VIRT_RESET_IIN_HISTORY, |
1240 | .attr = "reset_history", | 1239 | .attr = "reset_history", |
1241 | } | 1240 | } |
1242 | }; | 1241 | }; |
1243 | 1242 | ||
1244 | static const struct pmbus_limit_attr iout_limit_attrs[] = { | 1243 | static const struct pmbus_limit_attr iout_limit_attrs[] = { |
1245 | { | 1244 | { |
1246 | .reg = PMBUS_IOUT_OC_WARN_LIMIT, | 1245 | .reg = PMBUS_IOUT_OC_WARN_LIMIT, |
1247 | .attr = "max", | 1246 | .attr = "max", |
1248 | .alarm = "max_alarm", | 1247 | .alarm = "max_alarm", |
1249 | .sbit = PB_IOUT_OC_WARNING, | 1248 | .sbit = PB_IOUT_OC_WARNING, |
1250 | }, { | 1249 | }, { |
1251 | .reg = PMBUS_IOUT_UC_FAULT_LIMIT, | 1250 | .reg = PMBUS_IOUT_UC_FAULT_LIMIT, |
1252 | .attr = "lcrit", | 1251 | .attr = "lcrit", |
1253 | .alarm = "lcrit_alarm", | 1252 | .alarm = "lcrit_alarm", |
1254 | .sbit = PB_IOUT_UC_FAULT, | 1253 | .sbit = PB_IOUT_UC_FAULT, |
1255 | }, { | 1254 | }, { |
1256 | .reg = PMBUS_IOUT_OC_FAULT_LIMIT, | 1255 | .reg = PMBUS_IOUT_OC_FAULT_LIMIT, |
1257 | .attr = "crit", | 1256 | .attr = "crit", |
1258 | .alarm = "crit_alarm", | 1257 | .alarm = "crit_alarm", |
1259 | .sbit = PB_IOUT_OC_FAULT, | 1258 | .sbit = PB_IOUT_OC_FAULT, |
1260 | }, { | 1259 | }, { |
1261 | .reg = PMBUS_VIRT_READ_IOUT_AVG, | 1260 | .reg = PMBUS_VIRT_READ_IOUT_AVG, |
1262 | .update = true, | 1261 | .update = true, |
1263 | .attr = "average", | 1262 | .attr = "average", |
1264 | }, { | 1263 | }, { |
1265 | .reg = PMBUS_VIRT_READ_IOUT_MIN, | 1264 | .reg = PMBUS_VIRT_READ_IOUT_MIN, |
1266 | .update = true, | 1265 | .update = true, |
1267 | .attr = "lowest", | 1266 | .attr = "lowest", |
1268 | }, { | 1267 | }, { |
1269 | .reg = PMBUS_VIRT_READ_IOUT_MAX, | 1268 | .reg = PMBUS_VIRT_READ_IOUT_MAX, |
1270 | .update = true, | 1269 | .update = true, |
1271 | .attr = "highest", | 1270 | .attr = "highest", |
1272 | }, { | 1271 | }, { |
1273 | .reg = PMBUS_VIRT_RESET_IOUT_HISTORY, | 1272 | .reg = PMBUS_VIRT_RESET_IOUT_HISTORY, |
1274 | .attr = "reset_history", | 1273 | .attr = "reset_history", |
1275 | } | 1274 | } |
1276 | }; | 1275 | }; |
1277 | 1276 | ||
1278 | static const struct pmbus_sensor_attr current_attributes[] = { | 1277 | static const struct pmbus_sensor_attr current_attributes[] = { |
1279 | { | 1278 | { |
1280 | .reg = PMBUS_READ_IIN, | 1279 | .reg = PMBUS_READ_IIN, |
1281 | .class = PSC_CURRENT_IN, | 1280 | .class = PSC_CURRENT_IN, |
1282 | .label = "iin", | 1281 | .label = "iin", |
1283 | .func = PMBUS_HAVE_IIN, | 1282 | .func = PMBUS_HAVE_IIN, |
1284 | .sfunc = PMBUS_HAVE_STATUS_INPUT, | 1283 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
1285 | .sbase = PB_STATUS_INPUT_BASE, | 1284 | .sbase = PB_STATUS_INPUT_BASE, |
1286 | .limit = iin_limit_attrs, | 1285 | .limit = iin_limit_attrs, |
1287 | .nlimit = ARRAY_SIZE(iin_limit_attrs), | 1286 | .nlimit = ARRAY_SIZE(iin_limit_attrs), |
1288 | }, { | 1287 | }, { |
1289 | .reg = PMBUS_READ_IOUT, | 1288 | .reg = PMBUS_READ_IOUT, |
1290 | .class = PSC_CURRENT_OUT, | 1289 | .class = PSC_CURRENT_OUT, |
1291 | .label = "iout", | 1290 | .label = "iout", |
1292 | .paged = true, | 1291 | .paged = true, |
1293 | .func = PMBUS_HAVE_IOUT, | 1292 | .func = PMBUS_HAVE_IOUT, |
1294 | .sfunc = PMBUS_HAVE_STATUS_IOUT, | 1293 | .sfunc = PMBUS_HAVE_STATUS_IOUT, |
1295 | .sbase = PB_STATUS_IOUT_BASE, | 1294 | .sbase = PB_STATUS_IOUT_BASE, |
1296 | .gbit = PB_STATUS_IOUT_OC, | 1295 | .gbit = PB_STATUS_IOUT_OC, |
1297 | .limit = iout_limit_attrs, | 1296 | .limit = iout_limit_attrs, |
1298 | .nlimit = ARRAY_SIZE(iout_limit_attrs), | 1297 | .nlimit = ARRAY_SIZE(iout_limit_attrs), |
1299 | } | 1298 | } |
1300 | }; | 1299 | }; |
1301 | 1300 | ||
1302 | /* Power attributes */ | 1301 | /* Power attributes */ |
1303 | 1302 | ||
1304 | static const struct pmbus_limit_attr pin_limit_attrs[] = { | 1303 | static const struct pmbus_limit_attr pin_limit_attrs[] = { |
1305 | { | 1304 | { |
1306 | .reg = PMBUS_PIN_OP_WARN_LIMIT, | 1305 | .reg = PMBUS_PIN_OP_WARN_LIMIT, |
1307 | .attr = "max", | 1306 | .attr = "max", |
1308 | .alarm = "alarm", | 1307 | .alarm = "alarm", |
1309 | .sbit = PB_PIN_OP_WARNING, | 1308 | .sbit = PB_PIN_OP_WARNING, |
1310 | }, { | 1309 | }, { |
1311 | .reg = PMBUS_VIRT_READ_PIN_AVG, | 1310 | .reg = PMBUS_VIRT_READ_PIN_AVG, |
1312 | .update = true, | 1311 | .update = true, |
1313 | .attr = "average", | 1312 | .attr = "average", |
1314 | }, { | 1313 | }, { |
1315 | .reg = PMBUS_VIRT_READ_PIN_MAX, | 1314 | .reg = PMBUS_VIRT_READ_PIN_MAX, |
1316 | .update = true, | 1315 | .update = true, |
1317 | .attr = "input_highest", | 1316 | .attr = "input_highest", |
1318 | }, { | 1317 | }, { |
1319 | .reg = PMBUS_VIRT_RESET_PIN_HISTORY, | 1318 | .reg = PMBUS_VIRT_RESET_PIN_HISTORY, |
1320 | .attr = "reset_history", | 1319 | .attr = "reset_history", |
1321 | } | 1320 | } |
1322 | }; | 1321 | }; |
1323 | 1322 | ||
1324 | static const struct pmbus_limit_attr pout_limit_attrs[] = { | 1323 | static const struct pmbus_limit_attr pout_limit_attrs[] = { |
1325 | { | 1324 | { |
1326 | .reg = PMBUS_POUT_MAX, | 1325 | .reg = PMBUS_POUT_MAX, |
1327 | .attr = "cap", | 1326 | .attr = "cap", |
1328 | .alarm = "cap_alarm", | 1327 | .alarm = "cap_alarm", |
1329 | .sbit = PB_POWER_LIMITING, | 1328 | .sbit = PB_POWER_LIMITING, |
1330 | }, { | 1329 | }, { |
1331 | .reg = PMBUS_POUT_OP_WARN_LIMIT, | 1330 | .reg = PMBUS_POUT_OP_WARN_LIMIT, |
1332 | .attr = "max", | 1331 | .attr = "max", |
1333 | .alarm = "max_alarm", | 1332 | .alarm = "max_alarm", |
1334 | .sbit = PB_POUT_OP_WARNING, | 1333 | .sbit = PB_POUT_OP_WARNING, |
1335 | }, { | 1334 | }, { |
1336 | .reg = PMBUS_POUT_OP_FAULT_LIMIT, | 1335 | .reg = PMBUS_POUT_OP_FAULT_LIMIT, |
1337 | .attr = "crit", | 1336 | .attr = "crit", |
1338 | .alarm = "crit_alarm", | 1337 | .alarm = "crit_alarm", |
1339 | .sbit = PB_POUT_OP_FAULT, | 1338 | .sbit = PB_POUT_OP_FAULT, |
1340 | }, { | 1339 | }, { |
1341 | .reg = PMBUS_VIRT_READ_POUT_AVG, | 1340 | .reg = PMBUS_VIRT_READ_POUT_AVG, |
1342 | .update = true, | 1341 | .update = true, |
1343 | .attr = "average", | 1342 | .attr = "average", |
1344 | }, { | 1343 | }, { |
1345 | .reg = PMBUS_VIRT_READ_POUT_MAX, | 1344 | .reg = PMBUS_VIRT_READ_POUT_MAX, |
1346 | .update = true, | 1345 | .update = true, |
1347 | .attr = "input_highest", | 1346 | .attr = "input_highest", |
1348 | }, { | 1347 | }, { |
1349 | .reg = PMBUS_VIRT_RESET_POUT_HISTORY, | 1348 | .reg = PMBUS_VIRT_RESET_POUT_HISTORY, |
1350 | .attr = "reset_history", | 1349 | .attr = "reset_history", |
1351 | } | 1350 | } |
1352 | }; | 1351 | }; |
1353 | 1352 | ||
1354 | static const struct pmbus_sensor_attr power_attributes[] = { | 1353 | static const struct pmbus_sensor_attr power_attributes[] = { |
1355 | { | 1354 | { |
1356 | .reg = PMBUS_READ_PIN, | 1355 | .reg = PMBUS_READ_PIN, |
1357 | .class = PSC_POWER, | 1356 | .class = PSC_POWER, |
1358 | .label = "pin", | 1357 | .label = "pin", |
1359 | .func = PMBUS_HAVE_PIN, | 1358 | .func = PMBUS_HAVE_PIN, |
1360 | .sfunc = PMBUS_HAVE_STATUS_INPUT, | 1359 | .sfunc = PMBUS_HAVE_STATUS_INPUT, |
1361 | .sbase = PB_STATUS_INPUT_BASE, | 1360 | .sbase = PB_STATUS_INPUT_BASE, |
1362 | .limit = pin_limit_attrs, | 1361 | .limit = pin_limit_attrs, |
1363 | .nlimit = ARRAY_SIZE(pin_limit_attrs), | 1362 | .nlimit = ARRAY_SIZE(pin_limit_attrs), |
1364 | }, { | 1363 | }, { |
1365 | .reg = PMBUS_READ_POUT, | 1364 | .reg = PMBUS_READ_POUT, |
1366 | .class = PSC_POWER, | 1365 | .class = PSC_POWER, |
1367 | .label = "pout", | 1366 | .label = "pout", |
1368 | .paged = true, | 1367 | .paged = true, |
1369 | .func = PMBUS_HAVE_POUT, | 1368 | .func = PMBUS_HAVE_POUT, |
1370 | .sfunc = PMBUS_HAVE_STATUS_IOUT, | 1369 | .sfunc = PMBUS_HAVE_STATUS_IOUT, |
1371 | .sbase = PB_STATUS_IOUT_BASE, | 1370 | .sbase = PB_STATUS_IOUT_BASE, |
1372 | .limit = pout_limit_attrs, | 1371 | .limit = pout_limit_attrs, |
1373 | .nlimit = ARRAY_SIZE(pout_limit_attrs), | 1372 | .nlimit = ARRAY_SIZE(pout_limit_attrs), |
1374 | } | 1373 | } |
1375 | }; | 1374 | }; |
1376 | 1375 | ||
1377 | /* Temperature atributes */ | 1376 | /* Temperature atributes */ |
1378 | 1377 | ||
1379 | static const struct pmbus_limit_attr temp_limit_attrs[] = { | 1378 | static const struct pmbus_limit_attr temp_limit_attrs[] = { |
1380 | { | 1379 | { |
1381 | .reg = PMBUS_UT_WARN_LIMIT, | 1380 | .reg = PMBUS_UT_WARN_LIMIT, |
1382 | .low = true, | 1381 | .low = true, |
1383 | .attr = "min", | 1382 | .attr = "min", |
1384 | .alarm = "min_alarm", | 1383 | .alarm = "min_alarm", |
1385 | .sbit = PB_TEMP_UT_WARNING, | 1384 | .sbit = PB_TEMP_UT_WARNING, |
1386 | }, { | 1385 | }, { |
1387 | .reg = PMBUS_UT_FAULT_LIMIT, | 1386 | .reg = PMBUS_UT_FAULT_LIMIT, |
1388 | .low = true, | 1387 | .low = true, |
1389 | .attr = "lcrit", | 1388 | .attr = "lcrit", |
1390 | .alarm = "lcrit_alarm", | 1389 | .alarm = "lcrit_alarm", |
1391 | .sbit = PB_TEMP_UT_FAULT, | 1390 | .sbit = PB_TEMP_UT_FAULT, |
1392 | }, { | 1391 | }, { |
1393 | .reg = PMBUS_OT_WARN_LIMIT, | 1392 | .reg = PMBUS_OT_WARN_LIMIT, |
1394 | .attr = "max", | 1393 | .attr = "max", |
1395 | .alarm = "max_alarm", | 1394 | .alarm = "max_alarm", |
1396 | .sbit = PB_TEMP_OT_WARNING, | 1395 | .sbit = PB_TEMP_OT_WARNING, |
1397 | }, { | 1396 | }, { |
1398 | .reg = PMBUS_OT_FAULT_LIMIT, | 1397 | .reg = PMBUS_OT_FAULT_LIMIT, |
1399 | .attr = "crit", | 1398 | .attr = "crit", |
1400 | .alarm = "crit_alarm", | 1399 | .alarm = "crit_alarm", |
1401 | .sbit = PB_TEMP_OT_FAULT, | 1400 | .sbit = PB_TEMP_OT_FAULT, |
1402 | }, { | 1401 | }, { |
1403 | .reg = PMBUS_VIRT_READ_TEMP_MIN, | 1402 | .reg = PMBUS_VIRT_READ_TEMP_MIN, |
1404 | .attr = "lowest", | 1403 | .attr = "lowest", |
1405 | }, { | 1404 | }, { |
1406 | .reg = PMBUS_VIRT_READ_TEMP_AVG, | 1405 | .reg = PMBUS_VIRT_READ_TEMP_AVG, |
1407 | .attr = "average", | 1406 | .attr = "average", |
1408 | }, { | 1407 | }, { |
1409 | .reg = PMBUS_VIRT_READ_TEMP_MAX, | 1408 | .reg = PMBUS_VIRT_READ_TEMP_MAX, |
1410 | .attr = "highest", | 1409 | .attr = "highest", |
1411 | }, { | 1410 | }, { |
1412 | .reg = PMBUS_VIRT_RESET_TEMP_HISTORY, | 1411 | .reg = PMBUS_VIRT_RESET_TEMP_HISTORY, |
1413 | .attr = "reset_history", | 1412 | .attr = "reset_history", |
1414 | } | 1413 | } |
1415 | }; | 1414 | }; |
1416 | 1415 | ||
1417 | static const struct pmbus_limit_attr temp_limit_attrs2[] = { | 1416 | static const struct pmbus_limit_attr temp_limit_attrs2[] = { |
1418 | { | 1417 | { |
1419 | .reg = PMBUS_UT_WARN_LIMIT, | 1418 | .reg = PMBUS_UT_WARN_LIMIT, |
1420 | .low = true, | 1419 | .low = true, |
1421 | .attr = "min", | 1420 | .attr = "min", |
1422 | .alarm = "min_alarm", | 1421 | .alarm = "min_alarm", |
1423 | .sbit = PB_TEMP_UT_WARNING, | 1422 | .sbit = PB_TEMP_UT_WARNING, |
1424 | }, { | 1423 | }, { |
1425 | .reg = PMBUS_UT_FAULT_LIMIT, | 1424 | .reg = PMBUS_UT_FAULT_LIMIT, |
1426 | .low = true, | 1425 | .low = true, |
1427 | .attr = "lcrit", | 1426 | .attr = "lcrit", |
1428 | .alarm = "lcrit_alarm", | 1427 | .alarm = "lcrit_alarm", |
1429 | .sbit = PB_TEMP_UT_FAULT, | 1428 | .sbit = PB_TEMP_UT_FAULT, |
1430 | }, { | 1429 | }, { |
1431 | .reg = PMBUS_OT_WARN_LIMIT, | 1430 | .reg = PMBUS_OT_WARN_LIMIT, |
1432 | .attr = "max", | 1431 | .attr = "max", |
1433 | .alarm = "max_alarm", | 1432 | .alarm = "max_alarm", |
1434 | .sbit = PB_TEMP_OT_WARNING, | 1433 | .sbit = PB_TEMP_OT_WARNING, |
1435 | }, { | 1434 | }, { |
1436 | .reg = PMBUS_OT_FAULT_LIMIT, | 1435 | .reg = PMBUS_OT_FAULT_LIMIT, |
1437 | .attr = "crit", | 1436 | .attr = "crit", |
1438 | .alarm = "crit_alarm", | 1437 | .alarm = "crit_alarm", |
1439 | .sbit = PB_TEMP_OT_FAULT, | 1438 | .sbit = PB_TEMP_OT_FAULT, |
1440 | }, { | 1439 | }, { |
1441 | .reg = PMBUS_VIRT_READ_TEMP2_MIN, | 1440 | .reg = PMBUS_VIRT_READ_TEMP2_MIN, |
1442 | .attr = "lowest", | 1441 | .attr = "lowest", |
1443 | }, { | 1442 | }, { |
1444 | .reg = PMBUS_VIRT_READ_TEMP2_AVG, | 1443 | .reg = PMBUS_VIRT_READ_TEMP2_AVG, |
1445 | .attr = "average", | 1444 | .attr = "average", |
1446 | }, { | 1445 | }, { |
1447 | .reg = PMBUS_VIRT_READ_TEMP2_MAX, | 1446 | .reg = PMBUS_VIRT_READ_TEMP2_MAX, |
1448 | .attr = "highest", | 1447 | .attr = "highest", |
1449 | }, { | 1448 | }, { |
1450 | .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY, | 1449 | .reg = PMBUS_VIRT_RESET_TEMP2_HISTORY, |
1451 | .attr = "reset_history", | 1450 | .attr = "reset_history", |
1452 | } | 1451 | } |
1453 | }; | 1452 | }; |
1454 | 1453 | ||
1455 | static const struct pmbus_limit_attr temp_limit_attrs3[] = { | 1454 | static const struct pmbus_limit_attr temp_limit_attrs3[] = { |
1456 | { | 1455 | { |
1457 | .reg = PMBUS_UT_WARN_LIMIT, | 1456 | .reg = PMBUS_UT_WARN_LIMIT, |
1458 | .low = true, | 1457 | .low = true, |
1459 | .attr = "min", | 1458 | .attr = "min", |
1460 | .alarm = "min_alarm", | 1459 | .alarm = "min_alarm", |
1461 | .sbit = PB_TEMP_UT_WARNING, | 1460 | .sbit = PB_TEMP_UT_WARNING, |
1462 | }, { | 1461 | }, { |
1463 | .reg = PMBUS_UT_FAULT_LIMIT, | 1462 | .reg = PMBUS_UT_FAULT_LIMIT, |
1464 | .low = true, | 1463 | .low = true, |
1465 | .attr = "lcrit", | 1464 | .attr = "lcrit", |
1466 | .alarm = "lcrit_alarm", | 1465 | .alarm = "lcrit_alarm", |
1467 | .sbit = PB_TEMP_UT_FAULT, | 1466 | .sbit = PB_TEMP_UT_FAULT, |
1468 | }, { | 1467 | }, { |
1469 | .reg = PMBUS_OT_WARN_LIMIT, | 1468 | .reg = PMBUS_OT_WARN_LIMIT, |
1470 | .attr = "max", | 1469 | .attr = "max", |
1471 | .alarm = "max_alarm", | 1470 | .alarm = "max_alarm", |
1472 | .sbit = PB_TEMP_OT_WARNING, | 1471 | .sbit = PB_TEMP_OT_WARNING, |
1473 | }, { | 1472 | }, { |
1474 | .reg = PMBUS_OT_FAULT_LIMIT, | 1473 | .reg = PMBUS_OT_FAULT_LIMIT, |
1475 | .attr = "crit", | 1474 | .attr = "crit", |
1476 | .alarm = "crit_alarm", | 1475 | .alarm = "crit_alarm", |
1477 | .sbit = PB_TEMP_OT_FAULT, | 1476 | .sbit = PB_TEMP_OT_FAULT, |
1478 | } | 1477 | } |
1479 | }; | 1478 | }; |
1480 | 1479 | ||
1481 | static const struct pmbus_sensor_attr temp_attributes[] = { | 1480 | static const struct pmbus_sensor_attr temp_attributes[] = { |
1482 | { | 1481 | { |
1483 | .reg = PMBUS_READ_TEMPERATURE_1, | 1482 | .reg = PMBUS_READ_TEMPERATURE_1, |
1484 | .class = PSC_TEMPERATURE, | 1483 | .class = PSC_TEMPERATURE, |
1485 | .paged = true, | 1484 | .paged = true, |
1486 | .update = true, | 1485 | .update = true, |
1487 | .compare = true, | 1486 | .compare = true, |
1488 | .func = PMBUS_HAVE_TEMP, | 1487 | .func = PMBUS_HAVE_TEMP, |
1489 | .sfunc = PMBUS_HAVE_STATUS_TEMP, | 1488 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1490 | .sbase = PB_STATUS_TEMP_BASE, | 1489 | .sbase = PB_STATUS_TEMP_BASE, |
1491 | .gbit = PB_STATUS_TEMPERATURE, | 1490 | .gbit = PB_STATUS_TEMPERATURE, |
1492 | .limit = temp_limit_attrs, | 1491 | .limit = temp_limit_attrs, |
1493 | .nlimit = ARRAY_SIZE(temp_limit_attrs), | 1492 | .nlimit = ARRAY_SIZE(temp_limit_attrs), |
1494 | }, { | 1493 | }, { |
1495 | .reg = PMBUS_READ_TEMPERATURE_2, | 1494 | .reg = PMBUS_READ_TEMPERATURE_2, |
1496 | .class = PSC_TEMPERATURE, | 1495 | .class = PSC_TEMPERATURE, |
1497 | .paged = true, | 1496 | .paged = true, |
1498 | .update = true, | 1497 | .update = true, |
1499 | .compare = true, | 1498 | .compare = true, |
1500 | .func = PMBUS_HAVE_TEMP2, | 1499 | .func = PMBUS_HAVE_TEMP2, |
1501 | .sfunc = PMBUS_HAVE_STATUS_TEMP, | 1500 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1502 | .sbase = PB_STATUS_TEMP_BASE, | 1501 | .sbase = PB_STATUS_TEMP_BASE, |
1503 | .gbit = PB_STATUS_TEMPERATURE, | 1502 | .gbit = PB_STATUS_TEMPERATURE, |
1504 | .limit = temp_limit_attrs2, | 1503 | .limit = temp_limit_attrs2, |
1505 | .nlimit = ARRAY_SIZE(temp_limit_attrs2), | 1504 | .nlimit = ARRAY_SIZE(temp_limit_attrs2), |
1506 | }, { | 1505 | }, { |
1507 | .reg = PMBUS_READ_TEMPERATURE_3, | 1506 | .reg = PMBUS_READ_TEMPERATURE_3, |
1508 | .class = PSC_TEMPERATURE, | 1507 | .class = PSC_TEMPERATURE, |
1509 | .paged = true, | 1508 | .paged = true, |
1510 | .update = true, | 1509 | .update = true, |
1511 | .compare = true, | 1510 | .compare = true, |
1512 | .func = PMBUS_HAVE_TEMP3, | 1511 | .func = PMBUS_HAVE_TEMP3, |
1513 | .sfunc = PMBUS_HAVE_STATUS_TEMP, | 1512 | .sfunc = PMBUS_HAVE_STATUS_TEMP, |
1514 | .sbase = PB_STATUS_TEMP_BASE, | 1513 | .sbase = PB_STATUS_TEMP_BASE, |
1515 | .gbit = PB_STATUS_TEMPERATURE, | 1514 | .gbit = PB_STATUS_TEMPERATURE, |
1516 | .limit = temp_limit_attrs3, | 1515 | .limit = temp_limit_attrs3, |
1517 | .nlimit = ARRAY_SIZE(temp_limit_attrs3), | 1516 | .nlimit = ARRAY_SIZE(temp_limit_attrs3), |
1518 | } | 1517 | } |
1519 | }; | 1518 | }; |
1520 | 1519 | ||
1521 | static const int pmbus_fan_registers[] = { | 1520 | static const int pmbus_fan_registers[] = { |
1522 | PMBUS_READ_FAN_SPEED_1, | 1521 | PMBUS_READ_FAN_SPEED_1, |
1523 | PMBUS_READ_FAN_SPEED_2, | 1522 | PMBUS_READ_FAN_SPEED_2, |
1524 | PMBUS_READ_FAN_SPEED_3, | 1523 | PMBUS_READ_FAN_SPEED_3, |
1525 | PMBUS_READ_FAN_SPEED_4 | 1524 | PMBUS_READ_FAN_SPEED_4 |
1526 | }; | 1525 | }; |
1527 | 1526 | ||
1528 | static const int pmbus_fan_config_registers[] = { | 1527 | static const int pmbus_fan_config_registers[] = { |
1529 | PMBUS_FAN_CONFIG_12, | 1528 | PMBUS_FAN_CONFIG_12, |
1530 | PMBUS_FAN_CONFIG_12, | 1529 | PMBUS_FAN_CONFIG_12, |
1531 | PMBUS_FAN_CONFIG_34, | 1530 | PMBUS_FAN_CONFIG_34, |
1532 | PMBUS_FAN_CONFIG_34 | 1531 | PMBUS_FAN_CONFIG_34 |
1533 | }; | 1532 | }; |
1534 | 1533 | ||
1535 | static const int pmbus_fan_status_registers[] = { | 1534 | static const int pmbus_fan_status_registers[] = { |
1536 | PMBUS_STATUS_FAN_12, | 1535 | PMBUS_STATUS_FAN_12, |
1537 | PMBUS_STATUS_FAN_12, | 1536 | PMBUS_STATUS_FAN_12, |
1538 | PMBUS_STATUS_FAN_34, | 1537 | PMBUS_STATUS_FAN_34, |
1539 | PMBUS_STATUS_FAN_34 | 1538 | PMBUS_STATUS_FAN_34 |
1540 | }; | 1539 | }; |
1541 | 1540 | ||
1542 | static const u32 pmbus_fan_flags[] = { | 1541 | static const u32 pmbus_fan_flags[] = { |
1543 | PMBUS_HAVE_FAN12, | 1542 | PMBUS_HAVE_FAN12, |
1544 | PMBUS_HAVE_FAN12, | 1543 | PMBUS_HAVE_FAN12, |
1545 | PMBUS_HAVE_FAN34, | 1544 | PMBUS_HAVE_FAN34, |
1546 | PMBUS_HAVE_FAN34 | 1545 | PMBUS_HAVE_FAN34 |
1547 | }; | 1546 | }; |
1548 | 1547 | ||
1549 | static const u32 pmbus_fan_status_flags[] = { | 1548 | static const u32 pmbus_fan_status_flags[] = { |
1550 | PMBUS_HAVE_STATUS_FAN12, | 1549 | PMBUS_HAVE_STATUS_FAN12, |
1551 | PMBUS_HAVE_STATUS_FAN12, | 1550 | PMBUS_HAVE_STATUS_FAN12, |
1552 | PMBUS_HAVE_STATUS_FAN34, | 1551 | PMBUS_HAVE_STATUS_FAN34, |
1553 | PMBUS_HAVE_STATUS_FAN34 | 1552 | PMBUS_HAVE_STATUS_FAN34 |
1554 | }; | 1553 | }; |
1555 | 1554 | ||
1556 | /* Fans */ | 1555 | /* Fans */ |
1557 | static void pmbus_add_fan_attributes(struct i2c_client *client, | 1556 | static void pmbus_add_fan_attributes(struct i2c_client *client, |
1558 | struct pmbus_data *data) | 1557 | struct pmbus_data *data) |
1559 | { | 1558 | { |
1560 | const struct pmbus_driver_info *info = data->info; | 1559 | const struct pmbus_driver_info *info = data->info; |
1561 | int index = 1; | 1560 | int index = 1; |
1562 | int page; | 1561 | int page; |
1563 | 1562 | ||
1564 | for (page = 0; page < info->pages; page++) { | 1563 | for (page = 0; page < info->pages; page++) { |
1565 | int f; | 1564 | int f; |
1566 | 1565 | ||
1567 | for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) { | 1566 | for (f = 0; f < ARRAY_SIZE(pmbus_fan_registers); f++) { |
1568 | int regval; | 1567 | int regval; |
1569 | 1568 | ||
1570 | if (!(info->func[page] & pmbus_fan_flags[f])) | 1569 | if (!(info->func[page] & pmbus_fan_flags[f])) |
1571 | break; | 1570 | break; |
1572 | 1571 | ||
1573 | if (!pmbus_check_word_register(client, page, | 1572 | if (!pmbus_check_word_register(client, page, |
1574 | pmbus_fan_registers[f])) | 1573 | pmbus_fan_registers[f])) |
1575 | break; | 1574 | break; |
1576 | 1575 | ||
1577 | /* | 1576 | /* |
1578 | * Skip fan if not installed. | 1577 | * Skip fan if not installed. |
1579 | * Each fan configuration register covers multiple fans, | 1578 | * Each fan configuration register covers multiple fans, |
1580 | * so we have to do some magic. | 1579 | * so we have to do some magic. |
1581 | */ | 1580 | */ |
1582 | regval = _pmbus_read_byte_data(client, page, | 1581 | regval = _pmbus_read_byte_data(client, page, |
1583 | pmbus_fan_config_registers[f]); | 1582 | pmbus_fan_config_registers[f]); |
1584 | if (regval < 0 || | 1583 | if (regval < 0 || |
1585 | (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) | 1584 | (!(regval & (PB_FAN_1_INSTALLED >> ((f & 1) * 4))))) |
1586 | continue; | 1585 | continue; |
1587 | 1586 | ||
1588 | pmbus_add_sensor(data, "fan", "input", index, page, | 1587 | pmbus_add_sensor(data, "fan", "input", index, page, |
1589 | pmbus_fan_registers[f], PSC_FAN, true, | 1588 | pmbus_fan_registers[f], PSC_FAN, true, |
1590 | true); | 1589 | true); |
1591 | 1590 | ||
1592 | /* | 1591 | /* |
1593 | * Each fan status register covers multiple fans, | 1592 | * Each fan status register covers multiple fans, |
1594 | * so we have to do some magic. | 1593 | * so we have to do some magic. |
1595 | */ | 1594 | */ |
1596 | if ((info->func[page] & pmbus_fan_status_flags[f]) && | 1595 | if ((info->func[page] & pmbus_fan_status_flags[f]) && |
1597 | pmbus_check_byte_register(client, | 1596 | pmbus_check_byte_register(client, |
1598 | page, pmbus_fan_status_registers[f])) { | 1597 | page, pmbus_fan_status_registers[f])) { |
1599 | int base; | 1598 | int base; |
1600 | 1599 | ||
1601 | if (f > 1) /* fan 3, 4 */ | 1600 | if (f > 1) /* fan 3, 4 */ |
1602 | base = PB_STATUS_FAN34_BASE + page; | 1601 | base = PB_STATUS_FAN34_BASE + page; |
1603 | else | 1602 | else |
1604 | base = PB_STATUS_FAN_BASE + page; | 1603 | base = PB_STATUS_FAN_BASE + page; |
1605 | pmbus_add_boolean_reg(data, "fan", "alarm", | 1604 | pmbus_add_boolean_reg(data, "fan", "alarm", |
1606 | index, base, | 1605 | index, base, |
1607 | PB_FAN_FAN1_WARNING >> (f & 1)); | 1606 | PB_FAN_FAN1_WARNING >> (f & 1)); |
1608 | pmbus_add_boolean_reg(data, "fan", "fault", | 1607 | pmbus_add_boolean_reg(data, "fan", "fault", |
1609 | index, base, | 1608 | index, base, |
1610 | PB_FAN_FAN1_FAULT >> (f & 1)); | 1609 | PB_FAN_FAN1_FAULT >> (f & 1)); |
1611 | } | 1610 | } |
1612 | index++; | 1611 | index++; |
1613 | } | 1612 | } |
1614 | } | 1613 | } |
1615 | } | 1614 | } |
1616 | 1615 | ||
1617 | static void pmbus_find_attributes(struct i2c_client *client, | 1616 | static void pmbus_find_attributes(struct i2c_client *client, |
1618 | struct pmbus_data *data) | 1617 | struct pmbus_data *data) |
1619 | { | 1618 | { |
1620 | /* Voltage sensors */ | 1619 | /* Voltage sensors */ |
1621 | pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, | 1620 | pmbus_add_sensor_attrs(client, data, "in", voltage_attributes, |
1622 | ARRAY_SIZE(voltage_attributes)); | 1621 | ARRAY_SIZE(voltage_attributes)); |
1623 | 1622 | ||
1624 | /* Current sensors */ | 1623 | /* Current sensors */ |
1625 | pmbus_add_sensor_attrs(client, data, "curr", current_attributes, | 1624 | pmbus_add_sensor_attrs(client, data, "curr", current_attributes, |
1626 | ARRAY_SIZE(current_attributes)); | 1625 | ARRAY_SIZE(current_attributes)); |
1627 | 1626 | ||
1628 | /* Power sensors */ | 1627 | /* Power sensors */ |
1629 | pmbus_add_sensor_attrs(client, data, "power", power_attributes, | 1628 | pmbus_add_sensor_attrs(client, data, "power", power_attributes, |
1630 | ARRAY_SIZE(power_attributes)); | 1629 | ARRAY_SIZE(power_attributes)); |
1631 | 1630 | ||
1632 | /* Temperature sensors */ | 1631 | /* Temperature sensors */ |
1633 | pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, | 1632 | pmbus_add_sensor_attrs(client, data, "temp", temp_attributes, |
1634 | ARRAY_SIZE(temp_attributes)); | 1633 | ARRAY_SIZE(temp_attributes)); |
1635 | 1634 | ||
1636 | /* Fans */ | 1635 | /* Fans */ |
1637 | pmbus_add_fan_attributes(client, data); | 1636 | pmbus_add_fan_attributes(client, data); |
1638 | } | 1637 | } |
1639 | 1638 | ||
1640 | /* | 1639 | /* |
1641 | * Identify chip parameters. | 1640 | * Identify chip parameters. |
1642 | * This function is called for all chips. | 1641 | * This function is called for all chips. |
1643 | */ | 1642 | */ |
1644 | static int pmbus_identify_common(struct i2c_client *client, | 1643 | static int pmbus_identify_common(struct i2c_client *client, |
1645 | struct pmbus_data *data) | 1644 | struct pmbus_data *data) |
1646 | { | 1645 | { |
1647 | int vout_mode = -1; | 1646 | int vout_mode = -1; |
1648 | 1647 | ||
1649 | if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) | 1648 | if (pmbus_check_byte_register(client, 0, PMBUS_VOUT_MODE)) |
1650 | vout_mode = _pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); | 1649 | vout_mode = _pmbus_read_byte_data(client, 0, PMBUS_VOUT_MODE); |
1651 | if (vout_mode >= 0 && vout_mode != 0xff) { | 1650 | if (vout_mode >= 0 && vout_mode != 0xff) { |
1652 | /* | 1651 | /* |
1653 | * Not all chips support the VOUT_MODE command, | 1652 | * Not all chips support the VOUT_MODE command, |
1654 | * so a failure to read it is not an error. | 1653 | * so a failure to read it is not an error. |
1655 | */ | 1654 | */ |
1656 | switch (vout_mode >> 5) { | 1655 | switch (vout_mode >> 5) { |
1657 | case 0: /* linear mode */ | 1656 | case 0: /* linear mode */ |
1658 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) | 1657 | if (data->info->format[PSC_VOLTAGE_OUT] != linear) |
1659 | return -ENODEV; | 1658 | return -ENODEV; |
1660 | 1659 | ||
1661 | data->exponent = ((s8)(vout_mode << 3)) >> 3; | 1660 | data->exponent = ((s8)(vout_mode << 3)) >> 3; |
1662 | break; | 1661 | break; |
1663 | case 1: /* VID mode */ | 1662 | case 1: /* VID mode */ |
1664 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) | 1663 | if (data->info->format[PSC_VOLTAGE_OUT] != vid) |
1665 | return -ENODEV; | 1664 | return -ENODEV; |
1666 | break; | 1665 | break; |
1667 | case 2: /* direct mode */ | 1666 | case 2: /* direct mode */ |
1668 | if (data->info->format[PSC_VOLTAGE_OUT] != direct) | 1667 | if (data->info->format[PSC_VOLTAGE_OUT] != direct) |
1669 | return -ENODEV; | 1668 | return -ENODEV; |
1670 | break; | 1669 | break; |
1671 | default: | 1670 | default: |
1672 | return -ENODEV; | 1671 | return -ENODEV; |
1673 | } | 1672 | } |
1674 | } | 1673 | } |
1675 | 1674 | ||
1676 | /* Determine maximum number of sensors, booleans, and labels */ | 1675 | /* Determine maximum number of sensors, booleans, and labels */ |
1677 | pmbus_find_max_attr(client, data); | 1676 | pmbus_find_max_attr(client, data); |
1678 | pmbus_clear_fault_page(client, 0); | 1677 | pmbus_clear_fault_page(client, 0); |
1679 | return 0; | 1678 | return 0; |
1680 | } | 1679 | } |
1681 | 1680 | ||
1682 | int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, | 1681 | int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id, |
1683 | struct pmbus_driver_info *info) | 1682 | struct pmbus_driver_info *info) |
1684 | { | 1683 | { |
1685 | const struct pmbus_platform_data *pdata = client->dev.platform_data; | 1684 | const struct pmbus_platform_data *pdata = client->dev.platform_data; |
1686 | struct pmbus_data *data; | 1685 | struct pmbus_data *data; |
1687 | int ret; | 1686 | int ret; |
1688 | 1687 | ||
1689 | if (!info) { | 1688 | if (!info) { |
1690 | dev_err(&client->dev, "Missing chip information"); | 1689 | dev_err(&client->dev, "Missing chip information"); |
1691 | return -ENODEV; | 1690 | return -ENODEV; |
1692 | } | 1691 | } |
1693 | 1692 | ||
1694 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE | 1693 | if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE |
1695 | | I2C_FUNC_SMBUS_BYTE_DATA | 1694 | | I2C_FUNC_SMBUS_BYTE_DATA |
1696 | | I2C_FUNC_SMBUS_WORD_DATA)) | 1695 | | I2C_FUNC_SMBUS_WORD_DATA)) |
1697 | return -ENODEV; | 1696 | return -ENODEV; |
1698 | 1697 | ||
1699 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); | 1698 | data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL); |
1700 | if (!data) { | 1699 | if (!data) { |
1701 | dev_err(&client->dev, "No memory to allocate driver data\n"); | 1700 | dev_err(&client->dev, "No memory to allocate driver data\n"); |
1702 | return -ENOMEM; | 1701 | return -ENOMEM; |
1703 | } | 1702 | } |
1704 | 1703 | ||
1705 | i2c_set_clientdata(client, data); | 1704 | i2c_set_clientdata(client, data); |
1706 | mutex_init(&data->update_lock); | 1705 | mutex_init(&data->update_lock); |
1707 | 1706 | ||
1708 | /* Bail out if PMBus status register does not exist. */ | 1707 | /* Bail out if PMBus status register does not exist. */ |
1709 | if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) { | 1708 | if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) { |
1710 | dev_err(&client->dev, "PMBus status register not found\n"); | 1709 | dev_err(&client->dev, "PMBus status register not found\n"); |
1711 | return -ENODEV; | 1710 | return -ENODEV; |
1712 | } | 1711 | } |
1713 | 1712 | ||
1714 | if (pdata) | 1713 | if (pdata) |
1715 | data->flags = pdata->flags; | 1714 | data->flags = pdata->flags; |
1716 | data->info = info; | 1715 | data->info = info; |
1717 | 1716 | ||
1718 | pmbus_clear_faults(client); | 1717 | pmbus_clear_faults(client); |
1719 | 1718 | ||
1720 | if (info->identify) { | 1719 | if (info->identify) { |
1721 | ret = (*info->identify)(client, info); | 1720 | ret = (*info->identify)(client, info); |
1722 | if (ret < 0) { | 1721 | if (ret < 0) { |
1723 | dev_err(&client->dev, "Chip identification failed\n"); | 1722 | dev_err(&client->dev, "Chip identification failed\n"); |
1724 | return ret; | 1723 | return ret; |
1725 | } | 1724 | } |
1726 | } | 1725 | } |
1727 | 1726 | ||
1728 | if (info->pages <= 0 || info->pages > PMBUS_PAGES) { | 1727 | if (info->pages <= 0 || info->pages > PMBUS_PAGES) { |
1729 | dev_err(&client->dev, "Bad number of PMBus pages: %d\n", | 1728 | dev_err(&client->dev, "Bad number of PMBus pages: %d\n", |
1730 | info->pages); | 1729 | info->pages); |
1731 | return -ENODEV; | 1730 | return -ENODEV; |
1732 | } | 1731 | } |
1733 | 1732 | ||
1734 | ret = pmbus_identify_common(client, data); | 1733 | ret = pmbus_identify_common(client, data); |
1735 | if (ret < 0) { | 1734 | if (ret < 0) { |
1736 | dev_err(&client->dev, "Failed to identify chip capabilities\n"); | 1735 | dev_err(&client->dev, "Failed to identify chip capabilities\n"); |
1737 | return ret; | 1736 | return ret; |
1738 | } | 1737 | } |
1739 | 1738 | ||
1740 | ret = -ENOMEM; | 1739 | ret = -ENOMEM; |
1741 | data->sensors = devm_kzalloc(&client->dev, sizeof(struct pmbus_sensor) | 1740 | data->sensors = devm_kzalloc(&client->dev, sizeof(struct pmbus_sensor) |
1742 | * data->max_sensors, GFP_KERNEL); | 1741 | * data->max_sensors, GFP_KERNEL); |
1743 | if (!data->sensors) { | 1742 | if (!data->sensors) { |
1744 | dev_err(&client->dev, "No memory to allocate sensor data\n"); | 1743 | dev_err(&client->dev, "No memory to allocate sensor data\n"); |
1745 | return -ENOMEM; | 1744 | return -ENOMEM; |
1746 | } | 1745 | } |
1747 | 1746 | ||
1748 | data->booleans = devm_kzalloc(&client->dev, sizeof(struct pmbus_boolean) | 1747 | data->booleans = devm_kzalloc(&client->dev, sizeof(struct pmbus_boolean) |
1749 | * data->max_booleans, GFP_KERNEL); | 1748 | * data->max_booleans, GFP_KERNEL); |
1750 | if (!data->booleans) { | 1749 | if (!data->booleans) { |
1751 | dev_err(&client->dev, "No memory to allocate boolean data\n"); | 1750 | dev_err(&client->dev, "No memory to allocate boolean data\n"); |
1752 | return -ENOMEM; | 1751 | return -ENOMEM; |
1753 | } | 1752 | } |
1754 | 1753 | ||
1755 | data->labels = devm_kzalloc(&client->dev, sizeof(struct pmbus_label) | 1754 | data->labels = devm_kzalloc(&client->dev, sizeof(struct pmbus_label) |
1756 | * data->max_labels, GFP_KERNEL); | 1755 | * data->max_labels, GFP_KERNEL); |
1757 | if (!data->labels) { | 1756 | if (!data->labels) { |
1758 | dev_err(&client->dev, "No memory to allocate label data\n"); | 1757 | dev_err(&client->dev, "No memory to allocate label data\n"); |
1759 | return -ENOMEM; | 1758 | return -ENOMEM; |
1760 | } | 1759 | } |
1761 | 1760 | ||
1762 | data->attributes = devm_kzalloc(&client->dev, sizeof(struct attribute *) | 1761 | data->attributes = devm_kzalloc(&client->dev, sizeof(struct attribute *) |
1763 | * data->max_attributes, GFP_KERNEL); | 1762 | * data->max_attributes, GFP_KERNEL); |
1764 | if (!data->attributes) { | 1763 | if (!data->attributes) { |
1765 | dev_err(&client->dev, "No memory to allocate attribute data\n"); | 1764 | dev_err(&client->dev, "No memory to allocate attribute data\n"); |
1766 | return -ENOMEM; | 1765 | return -ENOMEM; |
1767 | } | 1766 | } |
1768 | 1767 | ||
1769 | pmbus_find_attributes(client, data); | 1768 | pmbus_find_attributes(client, data); |
1770 | 1769 | ||
1771 | /* | 1770 | /* |
1772 | * If there are no attributes, something is wrong. | 1771 | * If there are no attributes, something is wrong. |
1773 | * Bail out instead of trying to register nothing. | 1772 | * Bail out instead of trying to register nothing. |
1774 | */ | 1773 | */ |
1775 | if (!data->num_attributes) { | 1774 | if (!data->num_attributes) { |
1776 | dev_err(&client->dev, "No attributes found\n"); | 1775 | dev_err(&client->dev, "No attributes found\n"); |
1777 | return -ENODEV; | 1776 | return -ENODEV; |
1778 | } | 1777 | } |
1779 | 1778 | ||
1780 | /* Register sysfs hooks */ | 1779 | /* Register sysfs hooks */ |
1781 | data->group.attrs = data->attributes; | 1780 | data->group.attrs = data->attributes; |
1782 | ret = sysfs_create_group(&client->dev.kobj, &data->group); | 1781 | ret = sysfs_create_group(&client->dev.kobj, &data->group); |
1783 | if (ret) { | 1782 | if (ret) { |
1784 | dev_err(&client->dev, "Failed to create sysfs entries\n"); | 1783 | dev_err(&client->dev, "Failed to create sysfs entries\n"); |
1785 | return ret; | 1784 | return ret; |
1786 | } | 1785 | } |
1787 | data->hwmon_dev = hwmon_device_register(&client->dev); | 1786 | data->hwmon_dev = hwmon_device_register(&client->dev); |
1788 | if (IS_ERR(data->hwmon_dev)) { | 1787 | if (IS_ERR(data->hwmon_dev)) { |
1789 | ret = PTR_ERR(data->hwmon_dev); | 1788 | ret = PTR_ERR(data->hwmon_dev); |
1790 | dev_err(&client->dev, "Failed to register hwmon device\n"); | 1789 | dev_err(&client->dev, "Failed to register hwmon device\n"); |
1791 | goto out_hwmon_device_register; | 1790 | goto out_hwmon_device_register; |
1792 | } | 1791 | } |
1793 | return 0; | 1792 | return 0; |
1794 | 1793 | ||
1795 | out_hwmon_device_register: | 1794 | out_hwmon_device_register: |
1796 | sysfs_remove_group(&client->dev.kobj, &data->group); | 1795 | sysfs_remove_group(&client->dev.kobj, &data->group); |
1797 | return ret; | 1796 | return ret; |
1798 | } | 1797 | } |
1799 | EXPORT_SYMBOL_GPL(pmbus_do_probe); | 1798 | EXPORT_SYMBOL_GPL(pmbus_do_probe); |
1800 | 1799 | ||
1801 | int pmbus_do_remove(struct i2c_client *client) | 1800 | int pmbus_do_remove(struct i2c_client *client) |
1802 | { | 1801 | { |
1803 | struct pmbus_data *data = i2c_get_clientdata(client); | 1802 | struct pmbus_data *data = i2c_get_clientdata(client); |
1804 | hwmon_device_unregister(data->hwmon_dev); | 1803 | hwmon_device_unregister(data->hwmon_dev); |
1805 | sysfs_remove_group(&client->dev.kobj, &data->group); | 1804 | sysfs_remove_group(&client->dev.kobj, &data->group); |
1806 | return 0; | 1805 | return 0; |
1807 | } | 1806 | } |
1808 | EXPORT_SYMBOL_GPL(pmbus_do_remove); | 1807 | EXPORT_SYMBOL_GPL(pmbus_do_remove); |
1809 | 1808 | ||
1810 | MODULE_AUTHOR("Guenter Roeck"); | 1809 | MODULE_AUTHOR("Guenter Roeck"); |
1811 | MODULE_DESCRIPTION("PMBus core driver"); | 1810 | MODULE_DESCRIPTION("PMBus core driver"); |
1812 | MODULE_LICENSE("GPL"); | 1811 | MODULE_LICENSE("GPL"); |
1813 | 1812 |
drivers/hwmon/s3c-hwmon.c
1 | /* linux/drivers/hwmon/s3c-hwmon.c | 1 | /* linux/drivers/hwmon/s3c-hwmon.c |
2 | * | 2 | * |
3 | * Copyright (C) 2005, 2008, 2009 Simtec Electronics | 3 | * Copyright (C) 2005, 2008, 2009 Simtec Electronics |
4 | * http://armlinux.simtec.co.uk/ | 4 | * http://armlinux.simtec.co.uk/ |
5 | * Ben Dooks <ben@simtec.co.uk> | 5 | * Ben Dooks <ben@simtec.co.uk> |
6 | * | 6 | * |
7 | * S3C24XX/S3C64XX ADC hwmon support | 7 | * S3C24XX/S3C64XX ADC hwmon support |
8 | * | 8 | * |
9 | * This program is free software; you can redistribute it and/or modify | 9 | * This program is free software; you can redistribute it and/or modify |
10 | * it under the terms of the GNU General Public License version 2 as | 10 | * it under the terms of the GNU General Public License version 2 as |
11 | * published by the Free Software Foundation. | 11 | * published by the Free Software Foundation. |
12 | * | 12 | * |
13 | * This program is distributed in the hope that it will be useful, | 13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. | 16 | * GNU General Public License for more details. |
17 | * | 17 | * |
18 | * You should have received a copy of the GNU General Public License | 18 | * You should have received a copy of the GNU General Public License |
19 | * along with this program; if not, write to the Free Software | 19 | * along with this program; if not, write to the Free Software |
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
21 | */ | 21 | */ |
22 | 22 | ||
23 | #include <linux/module.h> | 23 | #include <linux/module.h> |
24 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
25 | #include <linux/delay.h> | ||
26 | #include <linux/io.h> | 25 | #include <linux/io.h> |
27 | #include <linux/init.h> | 26 | #include <linux/init.h> |
28 | #include <linux/err.h> | 27 | #include <linux/err.h> |
29 | #include <linux/clk.h> | 28 | #include <linux/clk.h> |
30 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
31 | #include <linux/platform_device.h> | 30 | #include <linux/platform_device.h> |
32 | 31 | ||
33 | #include <linux/hwmon.h> | 32 | #include <linux/hwmon.h> |
34 | #include <linux/hwmon-sysfs.h> | 33 | #include <linux/hwmon-sysfs.h> |
35 | 34 | ||
36 | #include <plat/adc.h> | 35 | #include <plat/adc.h> |
37 | #include <linux/platform_data/hwmon-s3c.h> | 36 | #include <linux/platform_data/hwmon-s3c.h> |
38 | 37 | ||
39 | struct s3c_hwmon_attr { | 38 | struct s3c_hwmon_attr { |
40 | struct sensor_device_attribute in; | 39 | struct sensor_device_attribute in; |
41 | struct sensor_device_attribute label; | 40 | struct sensor_device_attribute label; |
42 | char in_name[12]; | 41 | char in_name[12]; |
43 | char label_name[12]; | 42 | char label_name[12]; |
44 | }; | 43 | }; |
45 | 44 | ||
46 | /** | 45 | /** |
47 | * struct s3c_hwmon - ADC hwmon client information | 46 | * struct s3c_hwmon - ADC hwmon client information |
48 | * @lock: Access lock to serialise the conversions. | 47 | * @lock: Access lock to serialise the conversions. |
49 | * @client: The client we registered with the S3C ADC core. | 48 | * @client: The client we registered with the S3C ADC core. |
50 | * @hwmon_dev: The hwmon device we created. | 49 | * @hwmon_dev: The hwmon device we created. |
51 | * @attr: The holders for the channel attributes. | 50 | * @attr: The holders for the channel attributes. |
52 | */ | 51 | */ |
53 | struct s3c_hwmon { | 52 | struct s3c_hwmon { |
54 | struct mutex lock; | 53 | struct mutex lock; |
55 | struct s3c_adc_client *client; | 54 | struct s3c_adc_client *client; |
56 | struct device *hwmon_dev; | 55 | struct device *hwmon_dev; |
57 | 56 | ||
58 | struct s3c_hwmon_attr attrs[8]; | 57 | struct s3c_hwmon_attr attrs[8]; |
59 | }; | 58 | }; |
60 | 59 | ||
61 | /** | 60 | /** |
62 | * s3c_hwmon_read_ch - read a value from a given adc channel. | 61 | * s3c_hwmon_read_ch - read a value from a given adc channel. |
63 | * @dev: The device. | 62 | * @dev: The device. |
64 | * @hwmon: Our state. | 63 | * @hwmon: Our state. |
65 | * @channel: The channel we're reading from. | 64 | * @channel: The channel we're reading from. |
66 | * | 65 | * |
67 | * Read a value from the @channel with the proper locking and sleep until | 66 | * Read a value from the @channel with the proper locking and sleep until |
68 | * either the read completes or we timeout awaiting the ADC core to get | 67 | * either the read completes or we timeout awaiting the ADC core to get |
69 | * back to us. | 68 | * back to us. |
70 | */ | 69 | */ |
71 | static int s3c_hwmon_read_ch(struct device *dev, | 70 | static int s3c_hwmon_read_ch(struct device *dev, |
72 | struct s3c_hwmon *hwmon, int channel) | 71 | struct s3c_hwmon *hwmon, int channel) |
73 | { | 72 | { |
74 | int ret; | 73 | int ret; |
75 | 74 | ||
76 | ret = mutex_lock_interruptible(&hwmon->lock); | 75 | ret = mutex_lock_interruptible(&hwmon->lock); |
77 | if (ret < 0) | 76 | if (ret < 0) |
78 | return ret; | 77 | return ret; |
79 | 78 | ||
80 | dev_dbg(dev, "reading channel %d\n", channel); | 79 | dev_dbg(dev, "reading channel %d\n", channel); |
81 | 80 | ||
82 | ret = s3c_adc_read(hwmon->client, channel); | 81 | ret = s3c_adc_read(hwmon->client, channel); |
83 | mutex_unlock(&hwmon->lock); | 82 | mutex_unlock(&hwmon->lock); |
84 | 83 | ||
85 | return ret; | 84 | return ret; |
86 | } | 85 | } |
87 | 86 | ||
88 | #ifdef CONFIG_SENSORS_S3C_RAW | 87 | #ifdef CONFIG_SENSORS_S3C_RAW |
89 | /** | 88 | /** |
90 | * s3c_hwmon_show_raw - show a conversion from the raw channel number. | 89 | * s3c_hwmon_show_raw - show a conversion from the raw channel number. |
91 | * @dev: The device that the attribute belongs to. | 90 | * @dev: The device that the attribute belongs to. |
92 | * @attr: The attribute being read. | 91 | * @attr: The attribute being read. |
93 | * @buf: The result buffer. | 92 | * @buf: The result buffer. |
94 | * | 93 | * |
95 | * This show deals with the raw attribute, registered for each possible | 94 | * This show deals with the raw attribute, registered for each possible |
96 | * ADC channel. This does a conversion and returns the raw (un-scaled) | 95 | * ADC channel. This does a conversion and returns the raw (un-scaled) |
97 | * value returned from the hardware. | 96 | * value returned from the hardware. |
98 | */ | 97 | */ |
99 | static ssize_t s3c_hwmon_show_raw(struct device *dev, | 98 | static ssize_t s3c_hwmon_show_raw(struct device *dev, |
100 | struct device_attribute *attr, char *buf) | 99 | struct device_attribute *attr, char *buf) |
101 | { | 100 | { |
102 | struct s3c_hwmon *adc = platform_get_drvdata(to_platform_device(dev)); | 101 | struct s3c_hwmon *adc = platform_get_drvdata(to_platform_device(dev)); |
103 | struct sensor_device_attribute *sa = to_sensor_dev_attr(attr); | 102 | struct sensor_device_attribute *sa = to_sensor_dev_attr(attr); |
104 | int ret; | 103 | int ret; |
105 | 104 | ||
106 | ret = s3c_hwmon_read_ch(dev, adc, sa->index); | 105 | ret = s3c_hwmon_read_ch(dev, adc, sa->index); |
107 | 106 | ||
108 | return (ret < 0) ? ret : snprintf(buf, PAGE_SIZE, "%d\n", ret); | 107 | return (ret < 0) ? ret : snprintf(buf, PAGE_SIZE, "%d\n", ret); |
109 | } | 108 | } |
110 | 109 | ||
111 | #define DEF_ADC_ATTR(x) \ | 110 | #define DEF_ADC_ATTR(x) \ |
112 | static SENSOR_DEVICE_ATTR(adc##x##_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, x) | 111 | static SENSOR_DEVICE_ATTR(adc##x##_raw, S_IRUGO, s3c_hwmon_show_raw, NULL, x) |
113 | 112 | ||
114 | DEF_ADC_ATTR(0); | 113 | DEF_ADC_ATTR(0); |
115 | DEF_ADC_ATTR(1); | 114 | DEF_ADC_ATTR(1); |
116 | DEF_ADC_ATTR(2); | 115 | DEF_ADC_ATTR(2); |
117 | DEF_ADC_ATTR(3); | 116 | DEF_ADC_ATTR(3); |
118 | DEF_ADC_ATTR(4); | 117 | DEF_ADC_ATTR(4); |
119 | DEF_ADC_ATTR(5); | 118 | DEF_ADC_ATTR(5); |
120 | DEF_ADC_ATTR(6); | 119 | DEF_ADC_ATTR(6); |
121 | DEF_ADC_ATTR(7); | 120 | DEF_ADC_ATTR(7); |
122 | 121 | ||
123 | static struct attribute *s3c_hwmon_attrs[9] = { | 122 | static struct attribute *s3c_hwmon_attrs[9] = { |
124 | &sensor_dev_attr_adc0_raw.dev_attr.attr, | 123 | &sensor_dev_attr_adc0_raw.dev_attr.attr, |
125 | &sensor_dev_attr_adc1_raw.dev_attr.attr, | 124 | &sensor_dev_attr_adc1_raw.dev_attr.attr, |
126 | &sensor_dev_attr_adc2_raw.dev_attr.attr, | 125 | &sensor_dev_attr_adc2_raw.dev_attr.attr, |
127 | &sensor_dev_attr_adc3_raw.dev_attr.attr, | 126 | &sensor_dev_attr_adc3_raw.dev_attr.attr, |
128 | &sensor_dev_attr_adc4_raw.dev_attr.attr, | 127 | &sensor_dev_attr_adc4_raw.dev_attr.attr, |
129 | &sensor_dev_attr_adc5_raw.dev_attr.attr, | 128 | &sensor_dev_attr_adc5_raw.dev_attr.attr, |
130 | &sensor_dev_attr_adc6_raw.dev_attr.attr, | 129 | &sensor_dev_attr_adc6_raw.dev_attr.attr, |
131 | &sensor_dev_attr_adc7_raw.dev_attr.attr, | 130 | &sensor_dev_attr_adc7_raw.dev_attr.attr, |
132 | NULL, | 131 | NULL, |
133 | }; | 132 | }; |
134 | 133 | ||
135 | static struct attribute_group s3c_hwmon_attrgroup = { | 134 | static struct attribute_group s3c_hwmon_attrgroup = { |
136 | .attrs = s3c_hwmon_attrs, | 135 | .attrs = s3c_hwmon_attrs, |
137 | }; | 136 | }; |
138 | 137 | ||
139 | static inline int s3c_hwmon_add_raw(struct device *dev) | 138 | static inline int s3c_hwmon_add_raw(struct device *dev) |
140 | { | 139 | { |
141 | return sysfs_create_group(&dev->kobj, &s3c_hwmon_attrgroup); | 140 | return sysfs_create_group(&dev->kobj, &s3c_hwmon_attrgroup); |
142 | } | 141 | } |
143 | 142 | ||
144 | static inline void s3c_hwmon_remove_raw(struct device *dev) | 143 | static inline void s3c_hwmon_remove_raw(struct device *dev) |
145 | { | 144 | { |
146 | sysfs_remove_group(&dev->kobj, &s3c_hwmon_attrgroup); | 145 | sysfs_remove_group(&dev->kobj, &s3c_hwmon_attrgroup); |
147 | } | 146 | } |
148 | 147 | ||
149 | #else | 148 | #else |
150 | 149 | ||
151 | static inline int s3c_hwmon_add_raw(struct device *dev) { return 0; } | 150 | static inline int s3c_hwmon_add_raw(struct device *dev) { return 0; } |
152 | static inline void s3c_hwmon_remove_raw(struct device *dev) { } | 151 | static inline void s3c_hwmon_remove_raw(struct device *dev) { } |
153 | 152 | ||
154 | #endif /* CONFIG_SENSORS_S3C_RAW */ | 153 | #endif /* CONFIG_SENSORS_S3C_RAW */ |
155 | 154 | ||
156 | /** | 155 | /** |
157 | * s3c_hwmon_ch_show - show value of a given channel | 156 | * s3c_hwmon_ch_show - show value of a given channel |
158 | * @dev: The device that the attribute belongs to. | 157 | * @dev: The device that the attribute belongs to. |
159 | * @attr: The attribute being read. | 158 | * @attr: The attribute being read. |
160 | * @buf: The result buffer. | 159 | * @buf: The result buffer. |
161 | * | 160 | * |
162 | * Read a value from the ADC and scale it before returning it to the | 161 | * Read a value from the ADC and scale it before returning it to the |
163 | * caller. The scale factor is gained from the channel configuration | 162 | * caller. The scale factor is gained from the channel configuration |
164 | * passed via the platform data when the device was registered. | 163 | * passed via the platform data when the device was registered. |
165 | */ | 164 | */ |
166 | static ssize_t s3c_hwmon_ch_show(struct device *dev, | 165 | static ssize_t s3c_hwmon_ch_show(struct device *dev, |
167 | struct device_attribute *attr, | 166 | struct device_attribute *attr, |
168 | char *buf) | 167 | char *buf) |
169 | { | 168 | { |
170 | struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr); | 169 | struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr); |
171 | struct s3c_hwmon *hwmon = platform_get_drvdata(to_platform_device(dev)); | 170 | struct s3c_hwmon *hwmon = platform_get_drvdata(to_platform_device(dev)); |
172 | struct s3c_hwmon_pdata *pdata = dev->platform_data; | 171 | struct s3c_hwmon_pdata *pdata = dev->platform_data; |
173 | struct s3c_hwmon_chcfg *cfg; | 172 | struct s3c_hwmon_chcfg *cfg; |
174 | int ret; | 173 | int ret; |
175 | 174 | ||
176 | cfg = pdata->in[sen_attr->index]; | 175 | cfg = pdata->in[sen_attr->index]; |
177 | 176 | ||
178 | ret = s3c_hwmon_read_ch(dev, hwmon, sen_attr->index); | 177 | ret = s3c_hwmon_read_ch(dev, hwmon, sen_attr->index); |
179 | if (ret < 0) | 178 | if (ret < 0) |
180 | return ret; | 179 | return ret; |
181 | 180 | ||
182 | ret *= cfg->mult; | 181 | ret *= cfg->mult; |
183 | ret = DIV_ROUND_CLOSEST(ret, cfg->div); | 182 | ret = DIV_ROUND_CLOSEST(ret, cfg->div); |
184 | 183 | ||
185 | return snprintf(buf, PAGE_SIZE, "%d\n", ret); | 184 | return snprintf(buf, PAGE_SIZE, "%d\n", ret); |
186 | } | 185 | } |
187 | 186 | ||
188 | /** | 187 | /** |
189 | * s3c_hwmon_label_show - show label name of the given channel. | 188 | * s3c_hwmon_label_show - show label name of the given channel. |
190 | * @dev: The device that the attribute belongs to. | 189 | * @dev: The device that the attribute belongs to. |
191 | * @attr: The attribute being read. | 190 | * @attr: The attribute being read. |
192 | * @buf: The result buffer. | 191 | * @buf: The result buffer. |
193 | * | 192 | * |
194 | * Return the label name of a given channel | 193 | * Return the label name of a given channel |
195 | */ | 194 | */ |
196 | static ssize_t s3c_hwmon_label_show(struct device *dev, | 195 | static ssize_t s3c_hwmon_label_show(struct device *dev, |
197 | struct device_attribute *attr, | 196 | struct device_attribute *attr, |
198 | char *buf) | 197 | char *buf) |
199 | { | 198 | { |
200 | struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr); | 199 | struct sensor_device_attribute *sen_attr = to_sensor_dev_attr(attr); |
201 | struct s3c_hwmon_pdata *pdata = dev->platform_data; | 200 | struct s3c_hwmon_pdata *pdata = dev->platform_data; |
202 | struct s3c_hwmon_chcfg *cfg; | 201 | struct s3c_hwmon_chcfg *cfg; |
203 | 202 | ||
204 | cfg = pdata->in[sen_attr->index]; | 203 | cfg = pdata->in[sen_attr->index]; |
205 | 204 | ||
206 | return snprintf(buf, PAGE_SIZE, "%s\n", cfg->name); | 205 | return snprintf(buf, PAGE_SIZE, "%s\n", cfg->name); |
207 | } | 206 | } |
208 | 207 | ||
209 | /** | 208 | /** |
210 | * s3c_hwmon_create_attr - create hwmon attribute for given channel. | 209 | * s3c_hwmon_create_attr - create hwmon attribute for given channel. |
211 | * @dev: The device to create the attribute on. | 210 | * @dev: The device to create the attribute on. |
212 | * @cfg: The channel configuration passed from the platform data. | 211 | * @cfg: The channel configuration passed from the platform data. |
213 | * @channel: The ADC channel number to process. | 212 | * @channel: The ADC channel number to process. |
214 | * | 213 | * |
215 | * Create the scaled attribute for use with hwmon from the specified | 214 | * Create the scaled attribute for use with hwmon from the specified |
216 | * platform data in @pdata. The sysfs entry is handled by the routine | 215 | * platform data in @pdata. The sysfs entry is handled by the routine |
217 | * s3c_hwmon_ch_show(). | 216 | * s3c_hwmon_ch_show(). |
218 | * | 217 | * |
219 | * The attribute name is taken from the configuration data if present | 218 | * The attribute name is taken from the configuration data if present |
220 | * otherwise the name is taken by concatenating in_ with the channel | 219 | * otherwise the name is taken by concatenating in_ with the channel |
221 | * number. | 220 | * number. |
222 | */ | 221 | */ |
223 | static int s3c_hwmon_create_attr(struct device *dev, | 222 | static int s3c_hwmon_create_attr(struct device *dev, |
224 | struct s3c_hwmon_chcfg *cfg, | 223 | struct s3c_hwmon_chcfg *cfg, |
225 | struct s3c_hwmon_attr *attrs, | 224 | struct s3c_hwmon_attr *attrs, |
226 | int channel) | 225 | int channel) |
227 | { | 226 | { |
228 | struct sensor_device_attribute *attr; | 227 | struct sensor_device_attribute *attr; |
229 | int ret; | 228 | int ret; |
230 | 229 | ||
231 | snprintf(attrs->in_name, sizeof(attrs->in_name), "in%d_input", channel); | 230 | snprintf(attrs->in_name, sizeof(attrs->in_name), "in%d_input", channel); |
232 | 231 | ||
233 | attr = &attrs->in; | 232 | attr = &attrs->in; |
234 | attr->index = channel; | 233 | attr->index = channel; |
235 | sysfs_attr_init(&attr->dev_attr.attr); | 234 | sysfs_attr_init(&attr->dev_attr.attr); |
236 | attr->dev_attr.attr.name = attrs->in_name; | 235 | attr->dev_attr.attr.name = attrs->in_name; |
237 | attr->dev_attr.attr.mode = S_IRUGO; | 236 | attr->dev_attr.attr.mode = S_IRUGO; |
238 | attr->dev_attr.show = s3c_hwmon_ch_show; | 237 | attr->dev_attr.show = s3c_hwmon_ch_show; |
239 | 238 | ||
240 | ret = device_create_file(dev, &attr->dev_attr); | 239 | ret = device_create_file(dev, &attr->dev_attr); |
241 | if (ret < 0) { | 240 | if (ret < 0) { |
242 | dev_err(dev, "failed to create input attribute\n"); | 241 | dev_err(dev, "failed to create input attribute\n"); |
243 | return ret; | 242 | return ret; |
244 | } | 243 | } |
245 | 244 | ||
246 | /* if this has a name, add a label */ | 245 | /* if this has a name, add a label */ |
247 | if (cfg->name) { | 246 | if (cfg->name) { |
248 | snprintf(attrs->label_name, sizeof(attrs->label_name), | 247 | snprintf(attrs->label_name, sizeof(attrs->label_name), |
249 | "in%d_label", channel); | 248 | "in%d_label", channel); |
250 | 249 | ||
251 | attr = &attrs->label; | 250 | attr = &attrs->label; |
252 | attr->index = channel; | 251 | attr->index = channel; |
253 | sysfs_attr_init(&attr->dev_attr.attr); | 252 | sysfs_attr_init(&attr->dev_attr.attr); |
254 | attr->dev_attr.attr.name = attrs->label_name; | 253 | attr->dev_attr.attr.name = attrs->label_name; |
255 | attr->dev_attr.attr.mode = S_IRUGO; | 254 | attr->dev_attr.attr.mode = S_IRUGO; |
256 | attr->dev_attr.show = s3c_hwmon_label_show; | 255 | attr->dev_attr.show = s3c_hwmon_label_show; |
257 | 256 | ||
258 | ret = device_create_file(dev, &attr->dev_attr); | 257 | ret = device_create_file(dev, &attr->dev_attr); |
259 | if (ret < 0) { | 258 | if (ret < 0) { |
260 | device_remove_file(dev, &attrs->in.dev_attr); | 259 | device_remove_file(dev, &attrs->in.dev_attr); |
261 | dev_err(dev, "failed to create label attribute\n"); | 260 | dev_err(dev, "failed to create label attribute\n"); |
262 | } | 261 | } |
263 | } | 262 | } |
264 | 263 | ||
265 | return ret; | 264 | return ret; |
266 | } | 265 | } |
267 | 266 | ||
268 | static void s3c_hwmon_remove_attr(struct device *dev, | 267 | static void s3c_hwmon_remove_attr(struct device *dev, |
269 | struct s3c_hwmon_attr *attrs) | 268 | struct s3c_hwmon_attr *attrs) |
270 | { | 269 | { |
271 | device_remove_file(dev, &attrs->in.dev_attr); | 270 | device_remove_file(dev, &attrs->in.dev_attr); |
272 | device_remove_file(dev, &attrs->label.dev_attr); | 271 | device_remove_file(dev, &attrs->label.dev_attr); |
273 | } | 272 | } |
274 | 273 | ||
275 | /** | 274 | /** |
276 | * s3c_hwmon_probe - device probe entry. | 275 | * s3c_hwmon_probe - device probe entry. |
277 | * @dev: The device being probed. | 276 | * @dev: The device being probed. |
278 | */ | 277 | */ |
279 | static int __devinit s3c_hwmon_probe(struct platform_device *dev) | 278 | static int __devinit s3c_hwmon_probe(struct platform_device *dev) |
280 | { | 279 | { |
281 | struct s3c_hwmon_pdata *pdata = dev->dev.platform_data; | 280 | struct s3c_hwmon_pdata *pdata = dev->dev.platform_data; |
282 | struct s3c_hwmon *hwmon; | 281 | struct s3c_hwmon *hwmon; |
283 | int ret = 0; | 282 | int ret = 0; |
284 | int i; | 283 | int i; |
285 | 284 | ||
286 | if (!pdata) { | 285 | if (!pdata) { |
287 | dev_err(&dev->dev, "no platform data supplied\n"); | 286 | dev_err(&dev->dev, "no platform data supplied\n"); |
288 | return -EINVAL; | 287 | return -EINVAL; |
289 | } | 288 | } |
290 | 289 | ||
291 | hwmon = devm_kzalloc(&dev->dev, sizeof(struct s3c_hwmon), GFP_KERNEL); | 290 | hwmon = devm_kzalloc(&dev->dev, sizeof(struct s3c_hwmon), GFP_KERNEL); |
292 | if (hwmon == NULL) { | 291 | if (hwmon == NULL) { |
293 | dev_err(&dev->dev, "no memory\n"); | 292 | dev_err(&dev->dev, "no memory\n"); |
294 | return -ENOMEM; | 293 | return -ENOMEM; |
295 | } | 294 | } |
296 | 295 | ||
297 | platform_set_drvdata(dev, hwmon); | 296 | platform_set_drvdata(dev, hwmon); |
298 | 297 | ||
299 | mutex_init(&hwmon->lock); | 298 | mutex_init(&hwmon->lock); |
300 | 299 | ||
301 | /* Register with the core ADC driver. */ | 300 | /* Register with the core ADC driver. */ |
302 | 301 | ||
303 | hwmon->client = s3c_adc_register(dev, NULL, NULL, 0); | 302 | hwmon->client = s3c_adc_register(dev, NULL, NULL, 0); |
304 | if (IS_ERR(hwmon->client)) { | 303 | if (IS_ERR(hwmon->client)) { |
305 | dev_err(&dev->dev, "cannot register adc\n"); | 304 | dev_err(&dev->dev, "cannot register adc\n"); |
306 | return PTR_ERR(hwmon->client); | 305 | return PTR_ERR(hwmon->client); |
307 | } | 306 | } |
308 | 307 | ||
309 | /* add attributes for our adc devices. */ | 308 | /* add attributes for our adc devices. */ |
310 | 309 | ||
311 | ret = s3c_hwmon_add_raw(&dev->dev); | 310 | ret = s3c_hwmon_add_raw(&dev->dev); |
312 | if (ret) | 311 | if (ret) |
313 | goto err_registered; | 312 | goto err_registered; |
314 | 313 | ||
315 | /* register with the hwmon core */ | 314 | /* register with the hwmon core */ |
316 | 315 | ||
317 | hwmon->hwmon_dev = hwmon_device_register(&dev->dev); | 316 | hwmon->hwmon_dev = hwmon_device_register(&dev->dev); |
318 | if (IS_ERR(hwmon->hwmon_dev)) { | 317 | if (IS_ERR(hwmon->hwmon_dev)) { |
319 | dev_err(&dev->dev, "error registering with hwmon\n"); | 318 | dev_err(&dev->dev, "error registering with hwmon\n"); |
320 | ret = PTR_ERR(hwmon->hwmon_dev); | 319 | ret = PTR_ERR(hwmon->hwmon_dev); |
321 | goto err_raw_attribute; | 320 | goto err_raw_attribute; |
322 | } | 321 | } |
323 | 322 | ||
324 | for (i = 0; i < ARRAY_SIZE(pdata->in); i++) { | 323 | for (i = 0; i < ARRAY_SIZE(pdata->in); i++) { |
325 | struct s3c_hwmon_chcfg *cfg = pdata->in[i]; | 324 | struct s3c_hwmon_chcfg *cfg = pdata->in[i]; |
326 | 325 | ||
327 | if (!cfg) | 326 | if (!cfg) |
328 | continue; | 327 | continue; |
329 | 328 | ||
330 | if (cfg->mult >= 0x10000) | 329 | if (cfg->mult >= 0x10000) |
331 | dev_warn(&dev->dev, | 330 | dev_warn(&dev->dev, |
332 | "channel %d multiplier too large\n", | 331 | "channel %d multiplier too large\n", |
333 | i); | 332 | i); |
334 | 333 | ||
335 | if (cfg->div == 0) { | 334 | if (cfg->div == 0) { |
336 | dev_err(&dev->dev, "channel %d divider zero\n", i); | 335 | dev_err(&dev->dev, "channel %d divider zero\n", i); |
337 | continue; | 336 | continue; |
338 | } | 337 | } |
339 | 338 | ||
340 | ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i], | 339 | ret = s3c_hwmon_create_attr(&dev->dev, pdata->in[i], |
341 | &hwmon->attrs[i], i); | 340 | &hwmon->attrs[i], i); |
342 | if (ret) { | 341 | if (ret) { |
343 | dev_err(&dev->dev, | 342 | dev_err(&dev->dev, |
344 | "error creating channel %d\n", i); | 343 | "error creating channel %d\n", i); |
345 | 344 | ||
346 | for (i--; i >= 0; i--) | 345 | for (i--; i >= 0; i--) |
347 | s3c_hwmon_remove_attr(&dev->dev, | 346 | s3c_hwmon_remove_attr(&dev->dev, |
348 | &hwmon->attrs[i]); | 347 | &hwmon->attrs[i]); |
349 | 348 | ||
350 | goto err_hwmon_register; | 349 | goto err_hwmon_register; |
351 | } | 350 | } |
352 | } | 351 | } |
353 | 352 | ||
354 | return 0; | 353 | return 0; |
355 | 354 | ||
356 | err_hwmon_register: | 355 | err_hwmon_register: |
357 | hwmon_device_unregister(hwmon->hwmon_dev); | 356 | hwmon_device_unregister(hwmon->hwmon_dev); |
358 | 357 | ||
359 | err_raw_attribute: | 358 | err_raw_attribute: |
360 | s3c_hwmon_remove_raw(&dev->dev); | 359 | s3c_hwmon_remove_raw(&dev->dev); |
361 | 360 | ||
362 | err_registered: | 361 | err_registered: |
363 | s3c_adc_release(hwmon->client); | 362 | s3c_adc_release(hwmon->client); |
364 | 363 | ||
365 | return ret; | 364 | return ret; |
366 | } | 365 | } |
367 | 366 | ||
368 | static int __devexit s3c_hwmon_remove(struct platform_device *dev) | 367 | static int __devexit s3c_hwmon_remove(struct platform_device *dev) |
369 | { | 368 | { |
370 | struct s3c_hwmon *hwmon = platform_get_drvdata(dev); | 369 | struct s3c_hwmon *hwmon = platform_get_drvdata(dev); |
371 | int i; | 370 | int i; |
372 | 371 | ||
373 | s3c_hwmon_remove_raw(&dev->dev); | 372 | s3c_hwmon_remove_raw(&dev->dev); |
374 | 373 | ||
375 | for (i = 0; i < ARRAY_SIZE(hwmon->attrs); i++) | 374 | for (i = 0; i < ARRAY_SIZE(hwmon->attrs); i++) |
376 | s3c_hwmon_remove_attr(&dev->dev, &hwmon->attrs[i]); | 375 | s3c_hwmon_remove_attr(&dev->dev, &hwmon->attrs[i]); |
377 | 376 | ||
378 | hwmon_device_unregister(hwmon->hwmon_dev); | 377 | hwmon_device_unregister(hwmon->hwmon_dev); |
379 | s3c_adc_release(hwmon->client); | 378 | s3c_adc_release(hwmon->client); |
380 | 379 | ||
381 | return 0; | 380 | return 0; |
382 | } | 381 | } |
383 | 382 | ||
384 | static struct platform_driver s3c_hwmon_driver = { | 383 | static struct platform_driver s3c_hwmon_driver = { |
385 | .driver = { | 384 | .driver = { |
386 | .name = "s3c-hwmon", | 385 | .name = "s3c-hwmon", |
387 | .owner = THIS_MODULE, | 386 | .owner = THIS_MODULE, |
388 | }, | 387 | }, |
389 | .probe = s3c_hwmon_probe, | 388 | .probe = s3c_hwmon_probe, |
390 | .remove = __devexit_p(s3c_hwmon_remove), | 389 | .remove = __devexit_p(s3c_hwmon_remove), |
391 | }; | 390 | }; |
392 | 391 | ||
393 | module_platform_driver(s3c_hwmon_driver); | 392 | module_platform_driver(s3c_hwmon_driver); |
394 | 393 | ||
395 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); | 394 | MODULE_AUTHOR("Ben Dooks <ben@simtec.co.uk>"); |
396 | MODULE_DESCRIPTION("S3C ADC HWMon driver"); | 395 | MODULE_DESCRIPTION("S3C ADC HWMon driver"); |
397 | MODULE_LICENSE("GPL v2"); | 396 | MODULE_LICENSE("GPL v2"); |
398 | MODULE_ALIAS("platform:s3c-hwmon"); | 397 | MODULE_ALIAS("platform:s3c-hwmon"); |
399 | 398 |
drivers/hwmon/w83795.c
1 | /* | 1 | /* |
2 | * w83795.c - Linux kernel driver for hardware monitoring | 2 | * w83795.c - Linux kernel driver for hardware monitoring |
3 | * Copyright (C) 2008 Nuvoton Technology Corp. | 3 | * Copyright (C) 2008 Nuvoton Technology Corp. |
4 | * Wei Song | 4 | * Wei Song |
5 | * Copyright (C) 2010 Jean Delvare <khali@linux-fr.org> | 5 | * Copyright (C) 2010 Jean Delvare <khali@linux-fr.org> |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
8 | * it under the terms of the GNU General Public License as published by | 8 | * it under the terms of the GNU General Public License as published by |
9 | * the Free Software Foundation - version 2. | 9 | * the Free Software Foundation - version 2. |
10 | * | 10 | * |
11 | * This program is distributed in the hope that it will be useful, | 11 | * This program is distributed in the hope that it will be useful, |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
14 | * GNU General Public License for more details. | 14 | * GNU General Public License for more details. |
15 | * | 15 | * |
16 | * You should have received a copy of the GNU General Public License | 16 | * You should have received a copy of the GNU General Public License |
17 | * along with this program; if not, write to the Free Software | 17 | * along with this program; if not, write to the Free Software |
18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 18 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
19 | * 02110-1301 USA. | 19 | * 02110-1301 USA. |
20 | * | 20 | * |
21 | * Supports following chips: | 21 | * Supports following chips: |
22 | * | 22 | * |
23 | * Chip #vin #fanin #pwm #temp #dts wchipid vendid i2c ISA | 23 | * Chip #vin #fanin #pwm #temp #dts wchipid vendid i2c ISA |
24 | * w83795g 21 14 8 6 8 0x79 0x5ca3 yes no | 24 | * w83795g 21 14 8 6 8 0x79 0x5ca3 yes no |
25 | * w83795adg 18 14 2 6 8 0x79 0x5ca3 yes no | 25 | * w83795adg 18 14 2 6 8 0x79 0x5ca3 yes no |
26 | */ | 26 | */ |
27 | 27 | ||
28 | #include <linux/kernel.h> | 28 | #include <linux/kernel.h> |
29 | #include <linux/module.h> | 29 | #include <linux/module.h> |
30 | #include <linux/init.h> | 30 | #include <linux/init.h> |
31 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
32 | #include <linux/i2c.h> | 32 | #include <linux/i2c.h> |
33 | #include <linux/hwmon.h> | 33 | #include <linux/hwmon.h> |
34 | #include <linux/hwmon-sysfs.h> | 34 | #include <linux/hwmon-sysfs.h> |
35 | #include <linux/err.h> | 35 | #include <linux/err.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/delay.h> | ||
38 | #include <linux/jiffies.h> | 37 | #include <linux/jiffies.h> |
39 | 38 | ||
40 | /* Addresses to scan */ | 39 | /* Addresses to scan */ |
41 | static const unsigned short normal_i2c[] = { | 40 | static const unsigned short normal_i2c[] = { |
42 | 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END | 41 | 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END |
43 | }; | 42 | }; |
44 | 43 | ||
45 | 44 | ||
46 | static bool reset; | 45 | static bool reset; |
47 | module_param(reset, bool, 0); | 46 | module_param(reset, bool, 0); |
48 | MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); | 47 | MODULE_PARM_DESC(reset, "Set to 1 to reset chip, not recommended"); |
49 | 48 | ||
50 | 49 | ||
51 | #define W83795_REG_BANKSEL 0x00 | 50 | #define W83795_REG_BANKSEL 0x00 |
52 | #define W83795_REG_VENDORID 0xfd | 51 | #define W83795_REG_VENDORID 0xfd |
53 | #define W83795_REG_CHIPID 0xfe | 52 | #define W83795_REG_CHIPID 0xfe |
54 | #define W83795_REG_DEVICEID 0xfb | 53 | #define W83795_REG_DEVICEID 0xfb |
55 | #define W83795_REG_DEVICEID_A 0xff | 54 | #define W83795_REG_DEVICEID_A 0xff |
56 | 55 | ||
57 | #define W83795_REG_I2C_ADDR 0xfc | 56 | #define W83795_REG_I2C_ADDR 0xfc |
58 | #define W83795_REG_CONFIG 0x01 | 57 | #define W83795_REG_CONFIG 0x01 |
59 | #define W83795_REG_CONFIG_CONFIG48 0x04 | 58 | #define W83795_REG_CONFIG_CONFIG48 0x04 |
60 | #define W83795_REG_CONFIG_START 0x01 | 59 | #define W83795_REG_CONFIG_START 0x01 |
61 | 60 | ||
62 | /* Multi-Function Pin Ctrl Registers */ | 61 | /* Multi-Function Pin Ctrl Registers */ |
63 | #define W83795_REG_VOLT_CTRL1 0x02 | 62 | #define W83795_REG_VOLT_CTRL1 0x02 |
64 | #define W83795_REG_VOLT_CTRL2 0x03 | 63 | #define W83795_REG_VOLT_CTRL2 0x03 |
65 | #define W83795_REG_TEMP_CTRL1 0x04 | 64 | #define W83795_REG_TEMP_CTRL1 0x04 |
66 | #define W83795_REG_TEMP_CTRL2 0x05 | 65 | #define W83795_REG_TEMP_CTRL2 0x05 |
67 | #define W83795_REG_FANIN_CTRL1 0x06 | 66 | #define W83795_REG_FANIN_CTRL1 0x06 |
68 | #define W83795_REG_FANIN_CTRL2 0x07 | 67 | #define W83795_REG_FANIN_CTRL2 0x07 |
69 | #define W83795_REG_VMIGB_CTRL 0x08 | 68 | #define W83795_REG_VMIGB_CTRL 0x08 |
70 | 69 | ||
71 | #define TEMP_READ 0 | 70 | #define TEMP_READ 0 |
72 | #define TEMP_CRIT 1 | 71 | #define TEMP_CRIT 1 |
73 | #define TEMP_CRIT_HYST 2 | 72 | #define TEMP_CRIT_HYST 2 |
74 | #define TEMP_WARN 3 | 73 | #define TEMP_WARN 3 |
75 | #define TEMP_WARN_HYST 4 | 74 | #define TEMP_WARN_HYST 4 |
76 | /* | 75 | /* |
77 | * only crit and crit_hyst affect real-time alarm status | 76 | * only crit and crit_hyst affect real-time alarm status |
78 | * current crit crit_hyst warn warn_hyst | 77 | * current crit crit_hyst warn warn_hyst |
79 | */ | 78 | */ |
80 | static const u16 W83795_REG_TEMP[][5] = { | 79 | static const u16 W83795_REG_TEMP[][5] = { |
81 | {0x21, 0x96, 0x97, 0x98, 0x99}, /* TD1/TR1 */ | 80 | {0x21, 0x96, 0x97, 0x98, 0x99}, /* TD1/TR1 */ |
82 | {0x22, 0x9a, 0x9b, 0x9c, 0x9d}, /* TD2/TR2 */ | 81 | {0x22, 0x9a, 0x9b, 0x9c, 0x9d}, /* TD2/TR2 */ |
83 | {0x23, 0x9e, 0x9f, 0xa0, 0xa1}, /* TD3/TR3 */ | 82 | {0x23, 0x9e, 0x9f, 0xa0, 0xa1}, /* TD3/TR3 */ |
84 | {0x24, 0xa2, 0xa3, 0xa4, 0xa5}, /* TD4/TR4 */ | 83 | {0x24, 0xa2, 0xa3, 0xa4, 0xa5}, /* TD4/TR4 */ |
85 | {0x1f, 0xa6, 0xa7, 0xa8, 0xa9}, /* TR5 */ | 84 | {0x1f, 0xa6, 0xa7, 0xa8, 0xa9}, /* TR5 */ |
86 | {0x20, 0xaa, 0xab, 0xac, 0xad}, /* TR6 */ | 85 | {0x20, 0xaa, 0xab, 0xac, 0xad}, /* TR6 */ |
87 | }; | 86 | }; |
88 | 87 | ||
89 | #define IN_READ 0 | 88 | #define IN_READ 0 |
90 | #define IN_MAX 1 | 89 | #define IN_MAX 1 |
91 | #define IN_LOW 2 | 90 | #define IN_LOW 2 |
92 | static const u16 W83795_REG_IN[][3] = { | 91 | static const u16 W83795_REG_IN[][3] = { |
93 | /* Current, HL, LL */ | 92 | /* Current, HL, LL */ |
94 | {0x10, 0x70, 0x71}, /* VSEN1 */ | 93 | {0x10, 0x70, 0x71}, /* VSEN1 */ |
95 | {0x11, 0x72, 0x73}, /* VSEN2 */ | 94 | {0x11, 0x72, 0x73}, /* VSEN2 */ |
96 | {0x12, 0x74, 0x75}, /* VSEN3 */ | 95 | {0x12, 0x74, 0x75}, /* VSEN3 */ |
97 | {0x13, 0x76, 0x77}, /* VSEN4 */ | 96 | {0x13, 0x76, 0x77}, /* VSEN4 */ |
98 | {0x14, 0x78, 0x79}, /* VSEN5 */ | 97 | {0x14, 0x78, 0x79}, /* VSEN5 */ |
99 | {0x15, 0x7a, 0x7b}, /* VSEN6 */ | 98 | {0x15, 0x7a, 0x7b}, /* VSEN6 */ |
100 | {0x16, 0x7c, 0x7d}, /* VSEN7 */ | 99 | {0x16, 0x7c, 0x7d}, /* VSEN7 */ |
101 | {0x17, 0x7e, 0x7f}, /* VSEN8 */ | 100 | {0x17, 0x7e, 0x7f}, /* VSEN8 */ |
102 | {0x18, 0x80, 0x81}, /* VSEN9 */ | 101 | {0x18, 0x80, 0x81}, /* VSEN9 */ |
103 | {0x19, 0x82, 0x83}, /* VSEN10 */ | 102 | {0x19, 0x82, 0x83}, /* VSEN10 */ |
104 | {0x1A, 0x84, 0x85}, /* VSEN11 */ | 103 | {0x1A, 0x84, 0x85}, /* VSEN11 */ |
105 | {0x1B, 0x86, 0x87}, /* VTT */ | 104 | {0x1B, 0x86, 0x87}, /* VTT */ |
106 | {0x1C, 0x88, 0x89}, /* 3VDD */ | 105 | {0x1C, 0x88, 0x89}, /* 3VDD */ |
107 | {0x1D, 0x8a, 0x8b}, /* 3VSB */ | 106 | {0x1D, 0x8a, 0x8b}, /* 3VSB */ |
108 | {0x1E, 0x8c, 0x8d}, /* VBAT */ | 107 | {0x1E, 0x8c, 0x8d}, /* VBAT */ |
109 | {0x1F, 0xa6, 0xa7}, /* VSEN12 */ | 108 | {0x1F, 0xa6, 0xa7}, /* VSEN12 */ |
110 | {0x20, 0xaa, 0xab}, /* VSEN13 */ | 109 | {0x20, 0xaa, 0xab}, /* VSEN13 */ |
111 | {0x21, 0x96, 0x97}, /* VSEN14 */ | 110 | {0x21, 0x96, 0x97}, /* VSEN14 */ |
112 | {0x22, 0x9a, 0x9b}, /* VSEN15 */ | 111 | {0x22, 0x9a, 0x9b}, /* VSEN15 */ |
113 | {0x23, 0x9e, 0x9f}, /* VSEN16 */ | 112 | {0x23, 0x9e, 0x9f}, /* VSEN16 */ |
114 | {0x24, 0xa2, 0xa3}, /* VSEN17 */ | 113 | {0x24, 0xa2, 0xa3}, /* VSEN17 */ |
115 | }; | 114 | }; |
116 | #define W83795_REG_VRLSB 0x3C | 115 | #define W83795_REG_VRLSB 0x3C |
117 | 116 | ||
118 | static const u8 W83795_REG_IN_HL_LSB[] = { | 117 | static const u8 W83795_REG_IN_HL_LSB[] = { |
119 | 0x8e, /* VSEN1-4 */ | 118 | 0x8e, /* VSEN1-4 */ |
120 | 0x90, /* VSEN5-8 */ | 119 | 0x90, /* VSEN5-8 */ |
121 | 0x92, /* VSEN9-11 */ | 120 | 0x92, /* VSEN9-11 */ |
122 | 0x94, /* VTT, 3VDD, 3VSB, 3VBAT */ | 121 | 0x94, /* VTT, 3VDD, 3VSB, 3VBAT */ |
123 | 0xa8, /* VSEN12 */ | 122 | 0xa8, /* VSEN12 */ |
124 | 0xac, /* VSEN13 */ | 123 | 0xac, /* VSEN13 */ |
125 | 0x98, /* VSEN14 */ | 124 | 0x98, /* VSEN14 */ |
126 | 0x9c, /* VSEN15 */ | 125 | 0x9c, /* VSEN15 */ |
127 | 0xa0, /* VSEN16 */ | 126 | 0xa0, /* VSEN16 */ |
128 | 0xa4, /* VSEN17 */ | 127 | 0xa4, /* VSEN17 */ |
129 | }; | 128 | }; |
130 | 129 | ||
131 | #define IN_LSB_REG(index, type) \ | 130 | #define IN_LSB_REG(index, type) \ |
132 | (((type) == 1) ? W83795_REG_IN_HL_LSB[(index)] \ | 131 | (((type) == 1) ? W83795_REG_IN_HL_LSB[(index)] \ |
133 | : (W83795_REG_IN_HL_LSB[(index)] + 1)) | 132 | : (W83795_REG_IN_HL_LSB[(index)] + 1)) |
134 | 133 | ||
135 | #define IN_LSB_SHIFT 0 | 134 | #define IN_LSB_SHIFT 0 |
136 | #define IN_LSB_IDX 1 | 135 | #define IN_LSB_IDX 1 |
137 | static const u8 IN_LSB_SHIFT_IDX[][2] = { | 136 | static const u8 IN_LSB_SHIFT_IDX[][2] = { |
138 | /* High/Low LSB shift, LSB No. */ | 137 | /* High/Low LSB shift, LSB No. */ |
139 | {0x00, 0x00}, /* VSEN1 */ | 138 | {0x00, 0x00}, /* VSEN1 */ |
140 | {0x02, 0x00}, /* VSEN2 */ | 139 | {0x02, 0x00}, /* VSEN2 */ |
141 | {0x04, 0x00}, /* VSEN3 */ | 140 | {0x04, 0x00}, /* VSEN3 */ |
142 | {0x06, 0x00}, /* VSEN4 */ | 141 | {0x06, 0x00}, /* VSEN4 */ |
143 | {0x00, 0x01}, /* VSEN5 */ | 142 | {0x00, 0x01}, /* VSEN5 */ |
144 | {0x02, 0x01}, /* VSEN6 */ | 143 | {0x02, 0x01}, /* VSEN6 */ |
145 | {0x04, 0x01}, /* VSEN7 */ | 144 | {0x04, 0x01}, /* VSEN7 */ |
146 | {0x06, 0x01}, /* VSEN8 */ | 145 | {0x06, 0x01}, /* VSEN8 */ |
147 | {0x00, 0x02}, /* VSEN9 */ | 146 | {0x00, 0x02}, /* VSEN9 */ |
148 | {0x02, 0x02}, /* VSEN10 */ | 147 | {0x02, 0x02}, /* VSEN10 */ |
149 | {0x04, 0x02}, /* VSEN11 */ | 148 | {0x04, 0x02}, /* VSEN11 */ |
150 | {0x00, 0x03}, /* VTT */ | 149 | {0x00, 0x03}, /* VTT */ |
151 | {0x02, 0x03}, /* 3VDD */ | 150 | {0x02, 0x03}, /* 3VDD */ |
152 | {0x04, 0x03}, /* 3VSB */ | 151 | {0x04, 0x03}, /* 3VSB */ |
153 | {0x06, 0x03}, /* VBAT */ | 152 | {0x06, 0x03}, /* VBAT */ |
154 | {0x06, 0x04}, /* VSEN12 */ | 153 | {0x06, 0x04}, /* VSEN12 */ |
155 | {0x06, 0x05}, /* VSEN13 */ | 154 | {0x06, 0x05}, /* VSEN13 */ |
156 | {0x06, 0x06}, /* VSEN14 */ | 155 | {0x06, 0x06}, /* VSEN14 */ |
157 | {0x06, 0x07}, /* VSEN15 */ | 156 | {0x06, 0x07}, /* VSEN15 */ |
158 | {0x06, 0x08}, /* VSEN16 */ | 157 | {0x06, 0x08}, /* VSEN16 */ |
159 | {0x06, 0x09}, /* VSEN17 */ | 158 | {0x06, 0x09}, /* VSEN17 */ |
160 | }; | 159 | }; |
161 | 160 | ||
162 | 161 | ||
163 | #define W83795_REG_FAN(index) (0x2E + (index)) | 162 | #define W83795_REG_FAN(index) (0x2E + (index)) |
164 | #define W83795_REG_FAN_MIN_HL(index) (0xB6 + (index)) | 163 | #define W83795_REG_FAN_MIN_HL(index) (0xB6 + (index)) |
165 | #define W83795_REG_FAN_MIN_LSB(index) (0xC4 + (index) / 2) | 164 | #define W83795_REG_FAN_MIN_LSB(index) (0xC4 + (index) / 2) |
166 | #define W83795_REG_FAN_MIN_LSB_SHIFT(index) \ | 165 | #define W83795_REG_FAN_MIN_LSB_SHIFT(index) \ |
167 | (((index) & 1) ? 4 : 0) | 166 | (((index) & 1) ? 4 : 0) |
168 | 167 | ||
169 | #define W83795_REG_VID_CTRL 0x6A | 168 | #define W83795_REG_VID_CTRL 0x6A |
170 | 169 | ||
171 | #define W83795_REG_ALARM_CTRL 0x40 | 170 | #define W83795_REG_ALARM_CTRL 0x40 |
172 | #define ALARM_CTRL_RTSACS (1 << 7) | 171 | #define ALARM_CTRL_RTSACS (1 << 7) |
173 | #define W83795_REG_ALARM(index) (0x41 + (index)) | 172 | #define W83795_REG_ALARM(index) (0x41 + (index)) |
174 | #define W83795_REG_CLR_CHASSIS 0x4D | 173 | #define W83795_REG_CLR_CHASSIS 0x4D |
175 | #define W83795_REG_BEEP(index) (0x50 + (index)) | 174 | #define W83795_REG_BEEP(index) (0x50 + (index)) |
176 | 175 | ||
177 | #define W83795_REG_OVT_CFG 0x58 | 176 | #define W83795_REG_OVT_CFG 0x58 |
178 | #define OVT_CFG_SEL (1 << 7) | 177 | #define OVT_CFG_SEL (1 << 7) |
179 | 178 | ||
180 | 179 | ||
181 | #define W83795_REG_FCMS1 0x201 | 180 | #define W83795_REG_FCMS1 0x201 |
182 | #define W83795_REG_FCMS2 0x208 | 181 | #define W83795_REG_FCMS2 0x208 |
183 | #define W83795_REG_TFMR(index) (0x202 + (index)) | 182 | #define W83795_REG_TFMR(index) (0x202 + (index)) |
184 | #define W83795_REG_FOMC 0x20F | 183 | #define W83795_REG_FOMC 0x20F |
185 | 184 | ||
186 | #define W83795_REG_TSS(index) (0x209 + (index)) | 185 | #define W83795_REG_TSS(index) (0x209 + (index)) |
187 | 186 | ||
188 | #define TSS_MAP_RESERVED 0xff | 187 | #define TSS_MAP_RESERVED 0xff |
189 | static const u8 tss_map[4][6] = { | 188 | static const u8 tss_map[4][6] = { |
190 | { 0, 1, 2, 3, 4, 5}, | 189 | { 0, 1, 2, 3, 4, 5}, |
191 | { 6, 7, 8, 9, 0, 1}, | 190 | { 6, 7, 8, 9, 0, 1}, |
192 | {10, 11, 12, 13, 2, 3}, | 191 | {10, 11, 12, 13, 2, 3}, |
193 | { 4, 5, 4, 5, TSS_MAP_RESERVED, TSS_MAP_RESERVED}, | 192 | { 4, 5, 4, 5, TSS_MAP_RESERVED, TSS_MAP_RESERVED}, |
194 | }; | 193 | }; |
195 | 194 | ||
196 | #define PWM_OUTPUT 0 | 195 | #define PWM_OUTPUT 0 |
197 | #define PWM_FREQ 1 | 196 | #define PWM_FREQ 1 |
198 | #define PWM_START 2 | 197 | #define PWM_START 2 |
199 | #define PWM_NONSTOP 3 | 198 | #define PWM_NONSTOP 3 |
200 | #define PWM_STOP_TIME 4 | 199 | #define PWM_STOP_TIME 4 |
201 | #define W83795_REG_PWM(index, nr) (0x210 + (nr) * 8 + (index)) | 200 | #define W83795_REG_PWM(index, nr) (0x210 + (nr) * 8 + (index)) |
202 | 201 | ||
203 | #define W83795_REG_FTSH(index) (0x240 + (index) * 2) | 202 | #define W83795_REG_FTSH(index) (0x240 + (index) * 2) |
204 | #define W83795_REG_FTSL(index) (0x241 + (index) * 2) | 203 | #define W83795_REG_FTSL(index) (0x241 + (index) * 2) |
205 | #define W83795_REG_TFTS 0x250 | 204 | #define W83795_REG_TFTS 0x250 |
206 | 205 | ||
207 | #define TEMP_PWM_TTTI 0 | 206 | #define TEMP_PWM_TTTI 0 |
208 | #define TEMP_PWM_CTFS 1 | 207 | #define TEMP_PWM_CTFS 1 |
209 | #define TEMP_PWM_HCT 2 | 208 | #define TEMP_PWM_HCT 2 |
210 | #define TEMP_PWM_HOT 3 | 209 | #define TEMP_PWM_HOT 3 |
211 | #define W83795_REG_TTTI(index) (0x260 + (index)) | 210 | #define W83795_REG_TTTI(index) (0x260 + (index)) |
212 | #define W83795_REG_CTFS(index) (0x268 + (index)) | 211 | #define W83795_REG_CTFS(index) (0x268 + (index)) |
213 | #define W83795_REG_HT(index) (0x270 + (index)) | 212 | #define W83795_REG_HT(index) (0x270 + (index)) |
214 | 213 | ||
215 | #define SF4_TEMP 0 | 214 | #define SF4_TEMP 0 |
216 | #define SF4_PWM 1 | 215 | #define SF4_PWM 1 |
217 | #define W83795_REG_SF4_TEMP(temp_num, index) \ | 216 | #define W83795_REG_SF4_TEMP(temp_num, index) \ |
218 | (0x280 + 0x10 * (temp_num) + (index)) | 217 | (0x280 + 0x10 * (temp_num) + (index)) |
219 | #define W83795_REG_SF4_PWM(temp_num, index) \ | 218 | #define W83795_REG_SF4_PWM(temp_num, index) \ |
220 | (0x288 + 0x10 * (temp_num) + (index)) | 219 | (0x288 + 0x10 * (temp_num) + (index)) |
221 | 220 | ||
222 | #define W83795_REG_DTSC 0x301 | 221 | #define W83795_REG_DTSC 0x301 |
223 | #define W83795_REG_DTSE 0x302 | 222 | #define W83795_REG_DTSE 0x302 |
224 | #define W83795_REG_DTS(index) (0x26 + (index)) | 223 | #define W83795_REG_DTS(index) (0x26 + (index)) |
225 | #define W83795_REG_PECI_TBASE(index) (0x320 + (index)) | 224 | #define W83795_REG_PECI_TBASE(index) (0x320 + (index)) |
226 | 225 | ||
227 | #define DTS_CRIT 0 | 226 | #define DTS_CRIT 0 |
228 | #define DTS_CRIT_HYST 1 | 227 | #define DTS_CRIT_HYST 1 |
229 | #define DTS_WARN 2 | 228 | #define DTS_WARN 2 |
230 | #define DTS_WARN_HYST 3 | 229 | #define DTS_WARN_HYST 3 |
231 | #define W83795_REG_DTS_EXT(index) (0xB2 + (index)) | 230 | #define W83795_REG_DTS_EXT(index) (0xB2 + (index)) |
232 | 231 | ||
233 | #define SETUP_PWM_DEFAULT 0 | 232 | #define SETUP_PWM_DEFAULT 0 |
234 | #define SETUP_PWM_UPTIME 1 | 233 | #define SETUP_PWM_UPTIME 1 |
235 | #define SETUP_PWM_DOWNTIME 2 | 234 | #define SETUP_PWM_DOWNTIME 2 |
236 | #define W83795_REG_SETUP_PWM(index) (0x20C + (index)) | 235 | #define W83795_REG_SETUP_PWM(index) (0x20C + (index)) |
237 | 236 | ||
238 | static inline u16 in_from_reg(u8 index, u16 val) | 237 | static inline u16 in_from_reg(u8 index, u16 val) |
239 | { | 238 | { |
240 | /* 3VDD, 3VSB and VBAT: 6 mV/bit; other inputs: 2 mV/bit */ | 239 | /* 3VDD, 3VSB and VBAT: 6 mV/bit; other inputs: 2 mV/bit */ |
241 | if (index >= 12 && index <= 14) | 240 | if (index >= 12 && index <= 14) |
242 | return val * 6; | 241 | return val * 6; |
243 | else | 242 | else |
244 | return val * 2; | 243 | return val * 2; |
245 | } | 244 | } |
246 | 245 | ||
247 | static inline u16 in_to_reg(u8 index, u16 val) | 246 | static inline u16 in_to_reg(u8 index, u16 val) |
248 | { | 247 | { |
249 | if (index >= 12 && index <= 14) | 248 | if (index >= 12 && index <= 14) |
250 | return val / 6; | 249 | return val / 6; |
251 | else | 250 | else |
252 | return val / 2; | 251 | return val / 2; |
253 | } | 252 | } |
254 | 253 | ||
255 | static inline unsigned long fan_from_reg(u16 val) | 254 | static inline unsigned long fan_from_reg(u16 val) |
256 | { | 255 | { |
257 | if ((val == 0xfff) || (val == 0)) | 256 | if ((val == 0xfff) || (val == 0)) |
258 | return 0; | 257 | return 0; |
259 | return 1350000UL / val; | 258 | return 1350000UL / val; |
260 | } | 259 | } |
261 | 260 | ||
262 | static inline u16 fan_to_reg(long rpm) | 261 | static inline u16 fan_to_reg(long rpm) |
263 | { | 262 | { |
264 | if (rpm <= 0) | 263 | if (rpm <= 0) |
265 | return 0x0fff; | 264 | return 0x0fff; |
266 | return SENSORS_LIMIT((1350000 + (rpm >> 1)) / rpm, 1, 0xffe); | 265 | return SENSORS_LIMIT((1350000 + (rpm >> 1)) / rpm, 1, 0xffe); |
267 | } | 266 | } |
268 | 267 | ||
269 | static inline unsigned long time_from_reg(u8 reg) | 268 | static inline unsigned long time_from_reg(u8 reg) |
270 | { | 269 | { |
271 | return reg * 100; | 270 | return reg * 100; |
272 | } | 271 | } |
273 | 272 | ||
274 | static inline u8 time_to_reg(unsigned long val) | 273 | static inline u8 time_to_reg(unsigned long val) |
275 | { | 274 | { |
276 | return SENSORS_LIMIT((val + 50) / 100, 0, 0xff); | 275 | return SENSORS_LIMIT((val + 50) / 100, 0, 0xff); |
277 | } | 276 | } |
278 | 277 | ||
279 | static inline long temp_from_reg(s8 reg) | 278 | static inline long temp_from_reg(s8 reg) |
280 | { | 279 | { |
281 | return reg * 1000; | 280 | return reg * 1000; |
282 | } | 281 | } |
283 | 282 | ||
284 | static inline s8 temp_to_reg(long val, s8 min, s8 max) | 283 | static inline s8 temp_to_reg(long val, s8 min, s8 max) |
285 | { | 284 | { |
286 | return SENSORS_LIMIT(val / 1000, min, max); | 285 | return SENSORS_LIMIT(val / 1000, min, max); |
287 | } | 286 | } |
288 | 287 | ||
289 | static const u16 pwm_freq_cksel0[16] = { | 288 | static const u16 pwm_freq_cksel0[16] = { |
290 | 1024, 512, 341, 256, 205, 171, 146, 128, | 289 | 1024, 512, 341, 256, 205, 171, 146, 128, |
291 | 85, 64, 32, 16, 8, 4, 2, 1 | 290 | 85, 64, 32, 16, 8, 4, 2, 1 |
292 | }; | 291 | }; |
293 | 292 | ||
294 | static unsigned int pwm_freq_from_reg(u8 reg, u16 clkin) | 293 | static unsigned int pwm_freq_from_reg(u8 reg, u16 clkin) |
295 | { | 294 | { |
296 | unsigned long base_clock; | 295 | unsigned long base_clock; |
297 | 296 | ||
298 | if (reg & 0x80) { | 297 | if (reg & 0x80) { |
299 | base_clock = clkin * 1000 / ((clkin == 48000) ? 384 : 256); | 298 | base_clock = clkin * 1000 / ((clkin == 48000) ? 384 : 256); |
300 | return base_clock / ((reg & 0x7f) + 1); | 299 | return base_clock / ((reg & 0x7f) + 1); |
301 | } else | 300 | } else |
302 | return pwm_freq_cksel0[reg & 0x0f]; | 301 | return pwm_freq_cksel0[reg & 0x0f]; |
303 | } | 302 | } |
304 | 303 | ||
305 | static u8 pwm_freq_to_reg(unsigned long val, u16 clkin) | 304 | static u8 pwm_freq_to_reg(unsigned long val, u16 clkin) |
306 | { | 305 | { |
307 | unsigned long base_clock; | 306 | unsigned long base_clock; |
308 | u8 reg0, reg1; | 307 | u8 reg0, reg1; |
309 | unsigned long best0, best1; | 308 | unsigned long best0, best1; |
310 | 309 | ||
311 | /* Best fit for cksel = 0 */ | 310 | /* Best fit for cksel = 0 */ |
312 | for (reg0 = 0; reg0 < ARRAY_SIZE(pwm_freq_cksel0) - 1; reg0++) { | 311 | for (reg0 = 0; reg0 < ARRAY_SIZE(pwm_freq_cksel0) - 1; reg0++) { |
313 | if (val > (pwm_freq_cksel0[reg0] + | 312 | if (val > (pwm_freq_cksel0[reg0] + |
314 | pwm_freq_cksel0[reg0 + 1]) / 2) | 313 | pwm_freq_cksel0[reg0 + 1]) / 2) |
315 | break; | 314 | break; |
316 | } | 315 | } |
317 | if (val < 375) /* cksel = 1 can't beat this */ | 316 | if (val < 375) /* cksel = 1 can't beat this */ |
318 | return reg0; | 317 | return reg0; |
319 | best0 = pwm_freq_cksel0[reg0]; | 318 | best0 = pwm_freq_cksel0[reg0]; |
320 | 319 | ||
321 | /* Best fit for cksel = 1 */ | 320 | /* Best fit for cksel = 1 */ |
322 | base_clock = clkin * 1000 / ((clkin == 48000) ? 384 : 256); | 321 | base_clock = clkin * 1000 / ((clkin == 48000) ? 384 : 256); |
323 | reg1 = SENSORS_LIMIT(DIV_ROUND_CLOSEST(base_clock, val), 1, 128); | 322 | reg1 = SENSORS_LIMIT(DIV_ROUND_CLOSEST(base_clock, val), 1, 128); |
324 | best1 = base_clock / reg1; | 323 | best1 = base_clock / reg1; |
325 | reg1 = 0x80 | (reg1 - 1); | 324 | reg1 = 0x80 | (reg1 - 1); |
326 | 325 | ||
327 | /* Choose the closest one */ | 326 | /* Choose the closest one */ |
328 | if (abs(val - best0) > abs(val - best1)) | 327 | if (abs(val - best0) > abs(val - best1)) |
329 | return reg1; | 328 | return reg1; |
330 | else | 329 | else |
331 | return reg0; | 330 | return reg0; |
332 | } | 331 | } |
333 | 332 | ||
334 | enum chip_types {w83795g, w83795adg}; | 333 | enum chip_types {w83795g, w83795adg}; |
335 | 334 | ||
336 | struct w83795_data { | 335 | struct w83795_data { |
337 | struct device *hwmon_dev; | 336 | struct device *hwmon_dev; |
338 | struct mutex update_lock; | 337 | struct mutex update_lock; |
339 | unsigned long last_updated; /* In jiffies */ | 338 | unsigned long last_updated; /* In jiffies */ |
340 | enum chip_types chip_type; | 339 | enum chip_types chip_type; |
341 | 340 | ||
342 | u8 bank; | 341 | u8 bank; |
343 | 342 | ||
344 | u32 has_in; /* Enable monitor VIN or not */ | 343 | u32 has_in; /* Enable monitor VIN or not */ |
345 | u8 has_dyn_in; /* Only in2-0 can have this */ | 344 | u8 has_dyn_in; /* Only in2-0 can have this */ |
346 | u16 in[21][3]; /* Register value, read/high/low */ | 345 | u16 in[21][3]; /* Register value, read/high/low */ |
347 | u8 in_lsb[10][3]; /* LSB Register value, high/low */ | 346 | u8 in_lsb[10][3]; /* LSB Register value, high/low */ |
348 | u8 has_gain; /* has gain: in17-20 * 8 */ | 347 | u8 has_gain; /* has gain: in17-20 * 8 */ |
349 | 348 | ||
350 | u16 has_fan; /* Enable fan14-1 or not */ | 349 | u16 has_fan; /* Enable fan14-1 or not */ |
351 | u16 fan[14]; /* Register value combine */ | 350 | u16 fan[14]; /* Register value combine */ |
352 | u16 fan_min[14]; /* Register value combine */ | 351 | u16 fan_min[14]; /* Register value combine */ |
353 | 352 | ||
354 | u8 has_temp; /* Enable monitor temp6-1 or not */ | 353 | u8 has_temp; /* Enable monitor temp6-1 or not */ |
355 | s8 temp[6][5]; /* current, crit, crit_hyst, warn, warn_hyst */ | 354 | s8 temp[6][5]; /* current, crit, crit_hyst, warn, warn_hyst */ |
356 | u8 temp_read_vrlsb[6]; | 355 | u8 temp_read_vrlsb[6]; |
357 | u8 temp_mode; /* Bit vector, 0 = TR, 1 = TD */ | 356 | u8 temp_mode; /* Bit vector, 0 = TR, 1 = TD */ |
358 | u8 temp_src[3]; /* Register value */ | 357 | u8 temp_src[3]; /* Register value */ |
359 | 358 | ||
360 | u8 enable_dts; /* | 359 | u8 enable_dts; /* |
361 | * Enable PECI and SB-TSI, | 360 | * Enable PECI and SB-TSI, |
362 | * bit 0: =1 enable, =0 disable, | 361 | * bit 0: =1 enable, =0 disable, |
363 | * bit 1: =1 AMD SB-TSI, =0 Intel PECI | 362 | * bit 1: =1 AMD SB-TSI, =0 Intel PECI |
364 | */ | 363 | */ |
365 | u8 has_dts; /* Enable monitor DTS temp */ | 364 | u8 has_dts; /* Enable monitor DTS temp */ |
366 | s8 dts[8]; /* Register value */ | 365 | s8 dts[8]; /* Register value */ |
367 | u8 dts_read_vrlsb[8]; /* Register value */ | 366 | u8 dts_read_vrlsb[8]; /* Register value */ |
368 | s8 dts_ext[4]; /* Register value */ | 367 | s8 dts_ext[4]; /* Register value */ |
369 | 368 | ||
370 | u8 has_pwm; /* | 369 | u8 has_pwm; /* |
371 | * 795g supports 8 pwm, 795adg only supports 2, | 370 | * 795g supports 8 pwm, 795adg only supports 2, |
372 | * no config register, only affected by chip | 371 | * no config register, only affected by chip |
373 | * type | 372 | * type |
374 | */ | 373 | */ |
375 | u8 pwm[8][5]; /* | 374 | u8 pwm[8][5]; /* |
376 | * Register value, output, freq, start, | 375 | * Register value, output, freq, start, |
377 | * non stop, stop time | 376 | * non stop, stop time |
378 | */ | 377 | */ |
379 | u16 clkin; /* CLKIN frequency in kHz */ | 378 | u16 clkin; /* CLKIN frequency in kHz */ |
380 | u8 pwm_fcms[2]; /* Register value */ | 379 | u8 pwm_fcms[2]; /* Register value */ |
381 | u8 pwm_tfmr[6]; /* Register value */ | 380 | u8 pwm_tfmr[6]; /* Register value */ |
382 | u8 pwm_fomc; /* Register value */ | 381 | u8 pwm_fomc; /* Register value */ |
383 | 382 | ||
384 | u16 target_speed[8]; /* | 383 | u16 target_speed[8]; /* |
385 | * Register value, target speed for speed | 384 | * Register value, target speed for speed |
386 | * cruise | 385 | * cruise |
387 | */ | 386 | */ |
388 | u8 tol_speed; /* tolerance of target speed */ | 387 | u8 tol_speed; /* tolerance of target speed */ |
389 | u8 pwm_temp[6][4]; /* TTTI, CTFS, HCT, HOT */ | 388 | u8 pwm_temp[6][4]; /* TTTI, CTFS, HCT, HOT */ |
390 | u8 sf4_reg[6][2][7]; /* 6 temp, temp/dcpwm, 7 registers */ | 389 | u8 sf4_reg[6][2][7]; /* 6 temp, temp/dcpwm, 7 registers */ |
391 | 390 | ||
392 | u8 setup_pwm[3]; /* Register value */ | 391 | u8 setup_pwm[3]; /* Register value */ |
393 | 392 | ||
394 | u8 alarms[6]; /* Register value */ | 393 | u8 alarms[6]; /* Register value */ |
395 | u8 enable_beep; | 394 | u8 enable_beep; |
396 | u8 beeps[6]; /* Register value */ | 395 | u8 beeps[6]; /* Register value */ |
397 | 396 | ||
398 | char valid; | 397 | char valid; |
399 | char valid_limits; | 398 | char valid_limits; |
400 | char valid_pwm_config; | 399 | char valid_pwm_config; |
401 | }; | 400 | }; |
402 | 401 | ||
403 | /* | 402 | /* |
404 | * Hardware access | 403 | * Hardware access |
405 | * We assume that nobdody can change the bank outside the driver. | 404 | * We assume that nobdody can change the bank outside the driver. |
406 | */ | 405 | */ |
407 | 406 | ||
408 | /* Must be called with data->update_lock held, except during initialization */ | 407 | /* Must be called with data->update_lock held, except during initialization */ |
409 | static int w83795_set_bank(struct i2c_client *client, u8 bank) | 408 | static int w83795_set_bank(struct i2c_client *client, u8 bank) |
410 | { | 409 | { |
411 | struct w83795_data *data = i2c_get_clientdata(client); | 410 | struct w83795_data *data = i2c_get_clientdata(client); |
412 | int err; | 411 | int err; |
413 | 412 | ||
414 | /* If the same bank is already set, nothing to do */ | 413 | /* If the same bank is already set, nothing to do */ |
415 | if ((data->bank & 0x07) == bank) | 414 | if ((data->bank & 0x07) == bank) |
416 | return 0; | 415 | return 0; |
417 | 416 | ||
418 | /* Change to new bank, preserve all other bits */ | 417 | /* Change to new bank, preserve all other bits */ |
419 | bank |= data->bank & ~0x07; | 418 | bank |= data->bank & ~0x07; |
420 | err = i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, bank); | 419 | err = i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, bank); |
421 | if (err < 0) { | 420 | if (err < 0) { |
422 | dev_err(&client->dev, | 421 | dev_err(&client->dev, |
423 | "Failed to set bank to %d, err %d\n", | 422 | "Failed to set bank to %d, err %d\n", |
424 | (int)bank, err); | 423 | (int)bank, err); |
425 | return err; | 424 | return err; |
426 | } | 425 | } |
427 | data->bank = bank; | 426 | data->bank = bank; |
428 | 427 | ||
429 | return 0; | 428 | return 0; |
430 | } | 429 | } |
431 | 430 | ||
432 | /* Must be called with data->update_lock held, except during initialization */ | 431 | /* Must be called with data->update_lock held, except during initialization */ |
433 | static u8 w83795_read(struct i2c_client *client, u16 reg) | 432 | static u8 w83795_read(struct i2c_client *client, u16 reg) |
434 | { | 433 | { |
435 | int err; | 434 | int err; |
436 | 435 | ||
437 | err = w83795_set_bank(client, reg >> 8); | 436 | err = w83795_set_bank(client, reg >> 8); |
438 | if (err < 0) | 437 | if (err < 0) |
439 | return 0x00; /* Arbitrary */ | 438 | return 0x00; /* Arbitrary */ |
440 | 439 | ||
441 | err = i2c_smbus_read_byte_data(client, reg & 0xff); | 440 | err = i2c_smbus_read_byte_data(client, reg & 0xff); |
442 | if (err < 0) { | 441 | if (err < 0) { |
443 | dev_err(&client->dev, | 442 | dev_err(&client->dev, |
444 | "Failed to read from register 0x%03x, err %d\n", | 443 | "Failed to read from register 0x%03x, err %d\n", |
445 | (int)reg, err); | 444 | (int)reg, err); |
446 | return 0x00; /* Arbitrary */ | 445 | return 0x00; /* Arbitrary */ |
447 | } | 446 | } |
448 | return err; | 447 | return err; |
449 | } | 448 | } |
450 | 449 | ||
451 | /* Must be called with data->update_lock held, except during initialization */ | 450 | /* Must be called with data->update_lock held, except during initialization */ |
452 | static int w83795_write(struct i2c_client *client, u16 reg, u8 value) | 451 | static int w83795_write(struct i2c_client *client, u16 reg, u8 value) |
453 | { | 452 | { |
454 | int err; | 453 | int err; |
455 | 454 | ||
456 | err = w83795_set_bank(client, reg >> 8); | 455 | err = w83795_set_bank(client, reg >> 8); |
457 | if (err < 0) | 456 | if (err < 0) |
458 | return err; | 457 | return err; |
459 | 458 | ||
460 | err = i2c_smbus_write_byte_data(client, reg & 0xff, value); | 459 | err = i2c_smbus_write_byte_data(client, reg & 0xff, value); |
461 | if (err < 0) | 460 | if (err < 0) |
462 | dev_err(&client->dev, | 461 | dev_err(&client->dev, |
463 | "Failed to write to register 0x%03x, err %d\n", | 462 | "Failed to write to register 0x%03x, err %d\n", |
464 | (int)reg, err); | 463 | (int)reg, err); |
465 | return err; | 464 | return err; |
466 | } | 465 | } |
467 | 466 | ||
468 | static void w83795_update_limits(struct i2c_client *client) | 467 | static void w83795_update_limits(struct i2c_client *client) |
469 | { | 468 | { |
470 | struct w83795_data *data = i2c_get_clientdata(client); | 469 | struct w83795_data *data = i2c_get_clientdata(client); |
471 | int i, limit; | 470 | int i, limit; |
472 | u8 lsb; | 471 | u8 lsb; |
473 | 472 | ||
474 | /* Read the voltage limits */ | 473 | /* Read the voltage limits */ |
475 | for (i = 0; i < ARRAY_SIZE(data->in); i++) { | 474 | for (i = 0; i < ARRAY_SIZE(data->in); i++) { |
476 | if (!(data->has_in & (1 << i))) | 475 | if (!(data->has_in & (1 << i))) |
477 | continue; | 476 | continue; |
478 | data->in[i][IN_MAX] = | 477 | data->in[i][IN_MAX] = |
479 | w83795_read(client, W83795_REG_IN[i][IN_MAX]); | 478 | w83795_read(client, W83795_REG_IN[i][IN_MAX]); |
480 | data->in[i][IN_LOW] = | 479 | data->in[i][IN_LOW] = |
481 | w83795_read(client, W83795_REG_IN[i][IN_LOW]); | 480 | w83795_read(client, W83795_REG_IN[i][IN_LOW]); |
482 | } | 481 | } |
483 | for (i = 0; i < ARRAY_SIZE(data->in_lsb); i++) { | 482 | for (i = 0; i < ARRAY_SIZE(data->in_lsb); i++) { |
484 | if ((i == 2 && data->chip_type == w83795adg) || | 483 | if ((i == 2 && data->chip_type == w83795adg) || |
485 | (i >= 4 && !(data->has_in & (1 << (i + 11))))) | 484 | (i >= 4 && !(data->has_in & (1 << (i + 11))))) |
486 | continue; | 485 | continue; |
487 | data->in_lsb[i][IN_MAX] = | 486 | data->in_lsb[i][IN_MAX] = |
488 | w83795_read(client, IN_LSB_REG(i, IN_MAX)); | 487 | w83795_read(client, IN_LSB_REG(i, IN_MAX)); |
489 | data->in_lsb[i][IN_LOW] = | 488 | data->in_lsb[i][IN_LOW] = |
490 | w83795_read(client, IN_LSB_REG(i, IN_LOW)); | 489 | w83795_read(client, IN_LSB_REG(i, IN_LOW)); |
491 | } | 490 | } |
492 | 491 | ||
493 | /* Read the fan limits */ | 492 | /* Read the fan limits */ |
494 | lsb = 0; /* Silent false gcc warning */ | 493 | lsb = 0; /* Silent false gcc warning */ |
495 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { | 494 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { |
496 | /* | 495 | /* |
497 | * Each register contains LSB for 2 fans, but we want to | 496 | * Each register contains LSB for 2 fans, but we want to |
498 | * read it only once to save time | 497 | * read it only once to save time |
499 | */ | 498 | */ |
500 | if ((i & 1) == 0 && (data->has_fan & (3 << i))) | 499 | if ((i & 1) == 0 && (data->has_fan & (3 << i))) |
501 | lsb = w83795_read(client, W83795_REG_FAN_MIN_LSB(i)); | 500 | lsb = w83795_read(client, W83795_REG_FAN_MIN_LSB(i)); |
502 | 501 | ||
503 | if (!(data->has_fan & (1 << i))) | 502 | if (!(data->has_fan & (1 << i))) |
504 | continue; | 503 | continue; |
505 | data->fan_min[i] = | 504 | data->fan_min[i] = |
506 | w83795_read(client, W83795_REG_FAN_MIN_HL(i)) << 4; | 505 | w83795_read(client, W83795_REG_FAN_MIN_HL(i)) << 4; |
507 | data->fan_min[i] |= | 506 | data->fan_min[i] |= |
508 | (lsb >> W83795_REG_FAN_MIN_LSB_SHIFT(i)) & 0x0F; | 507 | (lsb >> W83795_REG_FAN_MIN_LSB_SHIFT(i)) & 0x0F; |
509 | } | 508 | } |
510 | 509 | ||
511 | /* Read the temperature limits */ | 510 | /* Read the temperature limits */ |
512 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { | 511 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { |
513 | if (!(data->has_temp & (1 << i))) | 512 | if (!(data->has_temp & (1 << i))) |
514 | continue; | 513 | continue; |
515 | for (limit = TEMP_CRIT; limit <= TEMP_WARN_HYST; limit++) | 514 | for (limit = TEMP_CRIT; limit <= TEMP_WARN_HYST; limit++) |
516 | data->temp[i][limit] = | 515 | data->temp[i][limit] = |
517 | w83795_read(client, W83795_REG_TEMP[i][limit]); | 516 | w83795_read(client, W83795_REG_TEMP[i][limit]); |
518 | } | 517 | } |
519 | 518 | ||
520 | /* Read the DTS limits */ | 519 | /* Read the DTS limits */ |
521 | if (data->enable_dts) { | 520 | if (data->enable_dts) { |
522 | for (limit = DTS_CRIT; limit <= DTS_WARN_HYST; limit++) | 521 | for (limit = DTS_CRIT; limit <= DTS_WARN_HYST; limit++) |
523 | data->dts_ext[limit] = | 522 | data->dts_ext[limit] = |
524 | w83795_read(client, W83795_REG_DTS_EXT(limit)); | 523 | w83795_read(client, W83795_REG_DTS_EXT(limit)); |
525 | } | 524 | } |
526 | 525 | ||
527 | /* Read beep settings */ | 526 | /* Read beep settings */ |
528 | if (data->enable_beep) { | 527 | if (data->enable_beep) { |
529 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) | 528 | for (i = 0; i < ARRAY_SIZE(data->beeps); i++) |
530 | data->beeps[i] = | 529 | data->beeps[i] = |
531 | w83795_read(client, W83795_REG_BEEP(i)); | 530 | w83795_read(client, W83795_REG_BEEP(i)); |
532 | } | 531 | } |
533 | 532 | ||
534 | data->valid_limits = 1; | 533 | data->valid_limits = 1; |
535 | } | 534 | } |
536 | 535 | ||
537 | static struct w83795_data *w83795_update_pwm_config(struct device *dev) | 536 | static struct w83795_data *w83795_update_pwm_config(struct device *dev) |
538 | { | 537 | { |
539 | struct i2c_client *client = to_i2c_client(dev); | 538 | struct i2c_client *client = to_i2c_client(dev); |
540 | struct w83795_data *data = i2c_get_clientdata(client); | 539 | struct w83795_data *data = i2c_get_clientdata(client); |
541 | int i, tmp; | 540 | int i, tmp; |
542 | 541 | ||
543 | mutex_lock(&data->update_lock); | 542 | mutex_lock(&data->update_lock); |
544 | 543 | ||
545 | if (data->valid_pwm_config) | 544 | if (data->valid_pwm_config) |
546 | goto END; | 545 | goto END; |
547 | 546 | ||
548 | /* Read temperature source selection */ | 547 | /* Read temperature source selection */ |
549 | for (i = 0; i < ARRAY_SIZE(data->temp_src); i++) | 548 | for (i = 0; i < ARRAY_SIZE(data->temp_src); i++) |
550 | data->temp_src[i] = w83795_read(client, W83795_REG_TSS(i)); | 549 | data->temp_src[i] = w83795_read(client, W83795_REG_TSS(i)); |
551 | 550 | ||
552 | /* Read automatic fan speed control settings */ | 551 | /* Read automatic fan speed control settings */ |
553 | data->pwm_fcms[0] = w83795_read(client, W83795_REG_FCMS1); | 552 | data->pwm_fcms[0] = w83795_read(client, W83795_REG_FCMS1); |
554 | data->pwm_fcms[1] = w83795_read(client, W83795_REG_FCMS2); | 553 | data->pwm_fcms[1] = w83795_read(client, W83795_REG_FCMS2); |
555 | for (i = 0; i < ARRAY_SIZE(data->pwm_tfmr); i++) | 554 | for (i = 0; i < ARRAY_SIZE(data->pwm_tfmr); i++) |
556 | data->pwm_tfmr[i] = w83795_read(client, W83795_REG_TFMR(i)); | 555 | data->pwm_tfmr[i] = w83795_read(client, W83795_REG_TFMR(i)); |
557 | data->pwm_fomc = w83795_read(client, W83795_REG_FOMC); | 556 | data->pwm_fomc = w83795_read(client, W83795_REG_FOMC); |
558 | for (i = 0; i < data->has_pwm; i++) { | 557 | for (i = 0; i < data->has_pwm; i++) { |
559 | for (tmp = PWM_FREQ; tmp <= PWM_STOP_TIME; tmp++) | 558 | for (tmp = PWM_FREQ; tmp <= PWM_STOP_TIME; tmp++) |
560 | data->pwm[i][tmp] = | 559 | data->pwm[i][tmp] = |
561 | w83795_read(client, W83795_REG_PWM(i, tmp)); | 560 | w83795_read(client, W83795_REG_PWM(i, tmp)); |
562 | } | 561 | } |
563 | for (i = 0; i < ARRAY_SIZE(data->target_speed); i++) { | 562 | for (i = 0; i < ARRAY_SIZE(data->target_speed); i++) { |
564 | data->target_speed[i] = | 563 | data->target_speed[i] = |
565 | w83795_read(client, W83795_REG_FTSH(i)) << 4; | 564 | w83795_read(client, W83795_REG_FTSH(i)) << 4; |
566 | data->target_speed[i] |= | 565 | data->target_speed[i] |= |
567 | w83795_read(client, W83795_REG_FTSL(i)) >> 4; | 566 | w83795_read(client, W83795_REG_FTSL(i)) >> 4; |
568 | } | 567 | } |
569 | data->tol_speed = w83795_read(client, W83795_REG_TFTS) & 0x3f; | 568 | data->tol_speed = w83795_read(client, W83795_REG_TFTS) & 0x3f; |
570 | 569 | ||
571 | for (i = 0; i < ARRAY_SIZE(data->pwm_temp); i++) { | 570 | for (i = 0; i < ARRAY_SIZE(data->pwm_temp); i++) { |
572 | data->pwm_temp[i][TEMP_PWM_TTTI] = | 571 | data->pwm_temp[i][TEMP_PWM_TTTI] = |
573 | w83795_read(client, W83795_REG_TTTI(i)) & 0x7f; | 572 | w83795_read(client, W83795_REG_TTTI(i)) & 0x7f; |
574 | data->pwm_temp[i][TEMP_PWM_CTFS] = | 573 | data->pwm_temp[i][TEMP_PWM_CTFS] = |
575 | w83795_read(client, W83795_REG_CTFS(i)); | 574 | w83795_read(client, W83795_REG_CTFS(i)); |
576 | tmp = w83795_read(client, W83795_REG_HT(i)); | 575 | tmp = w83795_read(client, W83795_REG_HT(i)); |
577 | data->pwm_temp[i][TEMP_PWM_HCT] = tmp >> 4; | 576 | data->pwm_temp[i][TEMP_PWM_HCT] = tmp >> 4; |
578 | data->pwm_temp[i][TEMP_PWM_HOT] = tmp & 0x0f; | 577 | data->pwm_temp[i][TEMP_PWM_HOT] = tmp & 0x0f; |
579 | } | 578 | } |
580 | 579 | ||
581 | /* Read SmartFanIV trip points */ | 580 | /* Read SmartFanIV trip points */ |
582 | for (i = 0; i < ARRAY_SIZE(data->sf4_reg); i++) { | 581 | for (i = 0; i < ARRAY_SIZE(data->sf4_reg); i++) { |
583 | for (tmp = 0; tmp < 7; tmp++) { | 582 | for (tmp = 0; tmp < 7; tmp++) { |
584 | data->sf4_reg[i][SF4_TEMP][tmp] = | 583 | data->sf4_reg[i][SF4_TEMP][tmp] = |
585 | w83795_read(client, | 584 | w83795_read(client, |
586 | W83795_REG_SF4_TEMP(i, tmp)); | 585 | W83795_REG_SF4_TEMP(i, tmp)); |
587 | data->sf4_reg[i][SF4_PWM][tmp] = | 586 | data->sf4_reg[i][SF4_PWM][tmp] = |
588 | w83795_read(client, W83795_REG_SF4_PWM(i, tmp)); | 587 | w83795_read(client, W83795_REG_SF4_PWM(i, tmp)); |
589 | } | 588 | } |
590 | } | 589 | } |
591 | 590 | ||
592 | /* Read setup PWM */ | 591 | /* Read setup PWM */ |
593 | for (i = 0; i < ARRAY_SIZE(data->setup_pwm); i++) | 592 | for (i = 0; i < ARRAY_SIZE(data->setup_pwm); i++) |
594 | data->setup_pwm[i] = | 593 | data->setup_pwm[i] = |
595 | w83795_read(client, W83795_REG_SETUP_PWM(i)); | 594 | w83795_read(client, W83795_REG_SETUP_PWM(i)); |
596 | 595 | ||
597 | data->valid_pwm_config = 1; | 596 | data->valid_pwm_config = 1; |
598 | 597 | ||
599 | END: | 598 | END: |
600 | mutex_unlock(&data->update_lock); | 599 | mutex_unlock(&data->update_lock); |
601 | return data; | 600 | return data; |
602 | } | 601 | } |
603 | 602 | ||
604 | static struct w83795_data *w83795_update_device(struct device *dev) | 603 | static struct w83795_data *w83795_update_device(struct device *dev) |
605 | { | 604 | { |
606 | struct i2c_client *client = to_i2c_client(dev); | 605 | struct i2c_client *client = to_i2c_client(dev); |
607 | struct w83795_data *data = i2c_get_clientdata(client); | 606 | struct w83795_data *data = i2c_get_clientdata(client); |
608 | u16 tmp; | 607 | u16 tmp; |
609 | u8 intrusion; | 608 | u8 intrusion; |
610 | int i; | 609 | int i; |
611 | 610 | ||
612 | mutex_lock(&data->update_lock); | 611 | mutex_lock(&data->update_lock); |
613 | 612 | ||
614 | if (!data->valid_limits) | 613 | if (!data->valid_limits) |
615 | w83795_update_limits(client); | 614 | w83795_update_limits(client); |
616 | 615 | ||
617 | if (!(time_after(jiffies, data->last_updated + HZ * 2) | 616 | if (!(time_after(jiffies, data->last_updated + HZ * 2) |
618 | || !data->valid)) | 617 | || !data->valid)) |
619 | goto END; | 618 | goto END; |
620 | 619 | ||
621 | /* Update the voltages value */ | 620 | /* Update the voltages value */ |
622 | for (i = 0; i < ARRAY_SIZE(data->in); i++) { | 621 | for (i = 0; i < ARRAY_SIZE(data->in); i++) { |
623 | if (!(data->has_in & (1 << i))) | 622 | if (!(data->has_in & (1 << i))) |
624 | continue; | 623 | continue; |
625 | tmp = w83795_read(client, W83795_REG_IN[i][IN_READ]) << 2; | 624 | tmp = w83795_read(client, W83795_REG_IN[i][IN_READ]) << 2; |
626 | tmp |= w83795_read(client, W83795_REG_VRLSB) >> 6; | 625 | tmp |= w83795_read(client, W83795_REG_VRLSB) >> 6; |
627 | data->in[i][IN_READ] = tmp; | 626 | data->in[i][IN_READ] = tmp; |
628 | } | 627 | } |
629 | 628 | ||
630 | /* in0-2 can have dynamic limits (W83795G only) */ | 629 | /* in0-2 can have dynamic limits (W83795G only) */ |
631 | if (data->has_dyn_in) { | 630 | if (data->has_dyn_in) { |
632 | u8 lsb_max = w83795_read(client, IN_LSB_REG(0, IN_MAX)); | 631 | u8 lsb_max = w83795_read(client, IN_LSB_REG(0, IN_MAX)); |
633 | u8 lsb_low = w83795_read(client, IN_LSB_REG(0, IN_LOW)); | 632 | u8 lsb_low = w83795_read(client, IN_LSB_REG(0, IN_LOW)); |
634 | 633 | ||
635 | for (i = 0; i < 3; i++) { | 634 | for (i = 0; i < 3; i++) { |
636 | if (!(data->has_dyn_in & (1 << i))) | 635 | if (!(data->has_dyn_in & (1 << i))) |
637 | continue; | 636 | continue; |
638 | data->in[i][IN_MAX] = | 637 | data->in[i][IN_MAX] = |
639 | w83795_read(client, W83795_REG_IN[i][IN_MAX]); | 638 | w83795_read(client, W83795_REG_IN[i][IN_MAX]); |
640 | data->in[i][IN_LOW] = | 639 | data->in[i][IN_LOW] = |
641 | w83795_read(client, W83795_REG_IN[i][IN_LOW]); | 640 | w83795_read(client, W83795_REG_IN[i][IN_LOW]); |
642 | data->in_lsb[i][IN_MAX] = (lsb_max >> (2 * i)) & 0x03; | 641 | data->in_lsb[i][IN_MAX] = (lsb_max >> (2 * i)) & 0x03; |
643 | data->in_lsb[i][IN_LOW] = (lsb_low >> (2 * i)) & 0x03; | 642 | data->in_lsb[i][IN_LOW] = (lsb_low >> (2 * i)) & 0x03; |
644 | } | 643 | } |
645 | } | 644 | } |
646 | 645 | ||
647 | /* Update fan */ | 646 | /* Update fan */ |
648 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { | 647 | for (i = 0; i < ARRAY_SIZE(data->fan); i++) { |
649 | if (!(data->has_fan & (1 << i))) | 648 | if (!(data->has_fan & (1 << i))) |
650 | continue; | 649 | continue; |
651 | data->fan[i] = w83795_read(client, W83795_REG_FAN(i)) << 4; | 650 | data->fan[i] = w83795_read(client, W83795_REG_FAN(i)) << 4; |
652 | data->fan[i] |= w83795_read(client, W83795_REG_VRLSB) >> 4; | 651 | data->fan[i] |= w83795_read(client, W83795_REG_VRLSB) >> 4; |
653 | } | 652 | } |
654 | 653 | ||
655 | /* Update temperature */ | 654 | /* Update temperature */ |
656 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { | 655 | for (i = 0; i < ARRAY_SIZE(data->temp); i++) { |
657 | data->temp[i][TEMP_READ] = | 656 | data->temp[i][TEMP_READ] = |
658 | w83795_read(client, W83795_REG_TEMP[i][TEMP_READ]); | 657 | w83795_read(client, W83795_REG_TEMP[i][TEMP_READ]); |
659 | data->temp_read_vrlsb[i] = | 658 | data->temp_read_vrlsb[i] = |
660 | w83795_read(client, W83795_REG_VRLSB); | 659 | w83795_read(client, W83795_REG_VRLSB); |
661 | } | 660 | } |
662 | 661 | ||
663 | /* Update dts temperature */ | 662 | /* Update dts temperature */ |
664 | if (data->enable_dts) { | 663 | if (data->enable_dts) { |
665 | for (i = 0; i < ARRAY_SIZE(data->dts); i++) { | 664 | for (i = 0; i < ARRAY_SIZE(data->dts); i++) { |
666 | if (!(data->has_dts & (1 << i))) | 665 | if (!(data->has_dts & (1 << i))) |
667 | continue; | 666 | continue; |
668 | data->dts[i] = | 667 | data->dts[i] = |
669 | w83795_read(client, W83795_REG_DTS(i)); | 668 | w83795_read(client, W83795_REG_DTS(i)); |
670 | data->dts_read_vrlsb[i] = | 669 | data->dts_read_vrlsb[i] = |
671 | w83795_read(client, W83795_REG_VRLSB); | 670 | w83795_read(client, W83795_REG_VRLSB); |
672 | } | 671 | } |
673 | } | 672 | } |
674 | 673 | ||
675 | /* Update pwm output */ | 674 | /* Update pwm output */ |
676 | for (i = 0; i < data->has_pwm; i++) { | 675 | for (i = 0; i < data->has_pwm; i++) { |
677 | data->pwm[i][PWM_OUTPUT] = | 676 | data->pwm[i][PWM_OUTPUT] = |
678 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); | 677 | w83795_read(client, W83795_REG_PWM(i, PWM_OUTPUT)); |
679 | } | 678 | } |
680 | 679 | ||
681 | /* | 680 | /* |
682 | * Update intrusion and alarms | 681 | * Update intrusion and alarms |
683 | * It is important to read intrusion first, because reading from | 682 | * It is important to read intrusion first, because reading from |
684 | * register SMI STS6 clears the interrupt status temporarily. | 683 | * register SMI STS6 clears the interrupt status temporarily. |
685 | */ | 684 | */ |
686 | tmp = w83795_read(client, W83795_REG_ALARM_CTRL); | 685 | tmp = w83795_read(client, W83795_REG_ALARM_CTRL); |
687 | /* Switch to interrupt status for intrusion if needed */ | 686 | /* Switch to interrupt status for intrusion if needed */ |
688 | if (tmp & ALARM_CTRL_RTSACS) | 687 | if (tmp & ALARM_CTRL_RTSACS) |
689 | w83795_write(client, W83795_REG_ALARM_CTRL, | 688 | w83795_write(client, W83795_REG_ALARM_CTRL, |
690 | tmp & ~ALARM_CTRL_RTSACS); | 689 | tmp & ~ALARM_CTRL_RTSACS); |
691 | intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6); | 690 | intrusion = w83795_read(client, W83795_REG_ALARM(5)) & (1 << 6); |
692 | /* Switch to real-time alarms */ | 691 | /* Switch to real-time alarms */ |
693 | w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS); | 692 | w83795_write(client, W83795_REG_ALARM_CTRL, tmp | ALARM_CTRL_RTSACS); |
694 | for (i = 0; i < ARRAY_SIZE(data->alarms); i++) | 693 | for (i = 0; i < ARRAY_SIZE(data->alarms); i++) |
695 | data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); | 694 | data->alarms[i] = w83795_read(client, W83795_REG_ALARM(i)); |
696 | data->alarms[5] |= intrusion; | 695 | data->alarms[5] |= intrusion; |
697 | /* Restore original configuration if needed */ | 696 | /* Restore original configuration if needed */ |
698 | if (!(tmp & ALARM_CTRL_RTSACS)) | 697 | if (!(tmp & ALARM_CTRL_RTSACS)) |
699 | w83795_write(client, W83795_REG_ALARM_CTRL, | 698 | w83795_write(client, W83795_REG_ALARM_CTRL, |
700 | tmp & ~ALARM_CTRL_RTSACS); | 699 | tmp & ~ALARM_CTRL_RTSACS); |
701 | 700 | ||
702 | data->last_updated = jiffies; | 701 | data->last_updated = jiffies; |
703 | data->valid = 1; | 702 | data->valid = 1; |
704 | 703 | ||
705 | END: | 704 | END: |
706 | mutex_unlock(&data->update_lock); | 705 | mutex_unlock(&data->update_lock); |
707 | return data; | 706 | return data; |
708 | } | 707 | } |
709 | 708 | ||
710 | /* | 709 | /* |
711 | * Sysfs attributes | 710 | * Sysfs attributes |
712 | */ | 711 | */ |
713 | 712 | ||
714 | #define ALARM_STATUS 0 | 713 | #define ALARM_STATUS 0 |
715 | #define BEEP_ENABLE 1 | 714 | #define BEEP_ENABLE 1 |
716 | static ssize_t | 715 | static ssize_t |
717 | show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf) | 716 | show_alarm_beep(struct device *dev, struct device_attribute *attr, char *buf) |
718 | { | 717 | { |
719 | struct w83795_data *data = w83795_update_device(dev); | 718 | struct w83795_data *data = w83795_update_device(dev); |
720 | struct sensor_device_attribute_2 *sensor_attr = | 719 | struct sensor_device_attribute_2 *sensor_attr = |
721 | to_sensor_dev_attr_2(attr); | 720 | to_sensor_dev_attr_2(attr); |
722 | int nr = sensor_attr->nr; | 721 | int nr = sensor_attr->nr; |
723 | int index = sensor_attr->index >> 3; | 722 | int index = sensor_attr->index >> 3; |
724 | int bit = sensor_attr->index & 0x07; | 723 | int bit = sensor_attr->index & 0x07; |
725 | u8 val; | 724 | u8 val; |
726 | 725 | ||
727 | if (nr == ALARM_STATUS) | 726 | if (nr == ALARM_STATUS) |
728 | val = (data->alarms[index] >> bit) & 1; | 727 | val = (data->alarms[index] >> bit) & 1; |
729 | else /* BEEP_ENABLE */ | 728 | else /* BEEP_ENABLE */ |
730 | val = (data->beeps[index] >> bit) & 1; | 729 | val = (data->beeps[index] >> bit) & 1; |
731 | 730 | ||
732 | return sprintf(buf, "%u\n", val); | 731 | return sprintf(buf, "%u\n", val); |
733 | } | 732 | } |
734 | 733 | ||
735 | static ssize_t | 734 | static ssize_t |
736 | store_beep(struct device *dev, struct device_attribute *attr, | 735 | store_beep(struct device *dev, struct device_attribute *attr, |
737 | const char *buf, size_t count) | 736 | const char *buf, size_t count) |
738 | { | 737 | { |
739 | struct i2c_client *client = to_i2c_client(dev); | 738 | struct i2c_client *client = to_i2c_client(dev); |
740 | struct w83795_data *data = i2c_get_clientdata(client); | 739 | struct w83795_data *data = i2c_get_clientdata(client); |
741 | struct sensor_device_attribute_2 *sensor_attr = | 740 | struct sensor_device_attribute_2 *sensor_attr = |
742 | to_sensor_dev_attr_2(attr); | 741 | to_sensor_dev_attr_2(attr); |
743 | int index = sensor_attr->index >> 3; | 742 | int index = sensor_attr->index >> 3; |
744 | int shift = sensor_attr->index & 0x07; | 743 | int shift = sensor_attr->index & 0x07; |
745 | u8 beep_bit = 1 << shift; | 744 | u8 beep_bit = 1 << shift; |
746 | unsigned long val; | 745 | unsigned long val; |
747 | 746 | ||
748 | if (kstrtoul(buf, 10, &val) < 0) | 747 | if (kstrtoul(buf, 10, &val) < 0) |
749 | return -EINVAL; | 748 | return -EINVAL; |
750 | if (val != 0 && val != 1) | 749 | if (val != 0 && val != 1) |
751 | return -EINVAL; | 750 | return -EINVAL; |
752 | 751 | ||
753 | mutex_lock(&data->update_lock); | 752 | mutex_lock(&data->update_lock); |
754 | data->beeps[index] = w83795_read(client, W83795_REG_BEEP(index)); | 753 | data->beeps[index] = w83795_read(client, W83795_REG_BEEP(index)); |
755 | data->beeps[index] &= ~beep_bit; | 754 | data->beeps[index] &= ~beep_bit; |
756 | data->beeps[index] |= val << shift; | 755 | data->beeps[index] |= val << shift; |
757 | w83795_write(client, W83795_REG_BEEP(index), data->beeps[index]); | 756 | w83795_write(client, W83795_REG_BEEP(index), data->beeps[index]); |
758 | mutex_unlock(&data->update_lock); | 757 | mutex_unlock(&data->update_lock); |
759 | 758 | ||
760 | return count; | 759 | return count; |
761 | } | 760 | } |
762 | 761 | ||
763 | /* Write 0 to clear chassis alarm */ | 762 | /* Write 0 to clear chassis alarm */ |
764 | static ssize_t | 763 | static ssize_t |
765 | store_chassis_clear(struct device *dev, | 764 | store_chassis_clear(struct device *dev, |
766 | struct device_attribute *attr, const char *buf, | 765 | struct device_attribute *attr, const char *buf, |
767 | size_t count) | 766 | size_t count) |
768 | { | 767 | { |
769 | struct i2c_client *client = to_i2c_client(dev); | 768 | struct i2c_client *client = to_i2c_client(dev); |
770 | struct w83795_data *data = i2c_get_clientdata(client); | 769 | struct w83795_data *data = i2c_get_clientdata(client); |
771 | unsigned long val; | 770 | unsigned long val; |
772 | 771 | ||
773 | if (kstrtoul(buf, 10, &val) < 0 || val != 0) | 772 | if (kstrtoul(buf, 10, &val) < 0 || val != 0) |
774 | return -EINVAL; | 773 | return -EINVAL; |
775 | 774 | ||
776 | mutex_lock(&data->update_lock); | 775 | mutex_lock(&data->update_lock); |
777 | val = w83795_read(client, W83795_REG_CLR_CHASSIS); | 776 | val = w83795_read(client, W83795_REG_CLR_CHASSIS); |
778 | val |= 0x80; | 777 | val |= 0x80; |
779 | w83795_write(client, W83795_REG_CLR_CHASSIS, val); | 778 | w83795_write(client, W83795_REG_CLR_CHASSIS, val); |
780 | 779 | ||
781 | /* Clear status and force cache refresh */ | 780 | /* Clear status and force cache refresh */ |
782 | w83795_read(client, W83795_REG_ALARM(5)); | 781 | w83795_read(client, W83795_REG_ALARM(5)); |
783 | data->valid = 0; | 782 | data->valid = 0; |
784 | mutex_unlock(&data->update_lock); | 783 | mutex_unlock(&data->update_lock); |
785 | return count; | 784 | return count; |
786 | } | 785 | } |
787 | 786 | ||
788 | #define FAN_INPUT 0 | 787 | #define FAN_INPUT 0 |
789 | #define FAN_MIN 1 | 788 | #define FAN_MIN 1 |
790 | static ssize_t | 789 | static ssize_t |
791 | show_fan(struct device *dev, struct device_attribute *attr, char *buf) | 790 | show_fan(struct device *dev, struct device_attribute *attr, char *buf) |
792 | { | 791 | { |
793 | struct sensor_device_attribute_2 *sensor_attr = | 792 | struct sensor_device_attribute_2 *sensor_attr = |
794 | to_sensor_dev_attr_2(attr); | 793 | to_sensor_dev_attr_2(attr); |
795 | int nr = sensor_attr->nr; | 794 | int nr = sensor_attr->nr; |
796 | int index = sensor_attr->index; | 795 | int index = sensor_attr->index; |
797 | struct w83795_data *data = w83795_update_device(dev); | 796 | struct w83795_data *data = w83795_update_device(dev); |
798 | u16 val; | 797 | u16 val; |
799 | 798 | ||
800 | if (nr == FAN_INPUT) | 799 | if (nr == FAN_INPUT) |
801 | val = data->fan[index] & 0x0fff; | 800 | val = data->fan[index] & 0x0fff; |
802 | else | 801 | else |
803 | val = data->fan_min[index] & 0x0fff; | 802 | val = data->fan_min[index] & 0x0fff; |
804 | 803 | ||
805 | return sprintf(buf, "%lu\n", fan_from_reg(val)); | 804 | return sprintf(buf, "%lu\n", fan_from_reg(val)); |
806 | } | 805 | } |
807 | 806 | ||
808 | static ssize_t | 807 | static ssize_t |
809 | store_fan_min(struct device *dev, struct device_attribute *attr, | 808 | store_fan_min(struct device *dev, struct device_attribute *attr, |
810 | const char *buf, size_t count) | 809 | const char *buf, size_t count) |
811 | { | 810 | { |
812 | struct sensor_device_attribute_2 *sensor_attr = | 811 | struct sensor_device_attribute_2 *sensor_attr = |
813 | to_sensor_dev_attr_2(attr); | 812 | to_sensor_dev_attr_2(attr); |
814 | int index = sensor_attr->index; | 813 | int index = sensor_attr->index; |
815 | struct i2c_client *client = to_i2c_client(dev); | 814 | struct i2c_client *client = to_i2c_client(dev); |
816 | struct w83795_data *data = i2c_get_clientdata(client); | 815 | struct w83795_data *data = i2c_get_clientdata(client); |
817 | unsigned long val; | 816 | unsigned long val; |
818 | 817 | ||
819 | if (kstrtoul(buf, 10, &val)) | 818 | if (kstrtoul(buf, 10, &val)) |
820 | return -EINVAL; | 819 | return -EINVAL; |
821 | val = fan_to_reg(val); | 820 | val = fan_to_reg(val); |
822 | 821 | ||
823 | mutex_lock(&data->update_lock); | 822 | mutex_lock(&data->update_lock); |
824 | data->fan_min[index] = val; | 823 | data->fan_min[index] = val; |
825 | w83795_write(client, W83795_REG_FAN_MIN_HL(index), (val >> 4) & 0xff); | 824 | w83795_write(client, W83795_REG_FAN_MIN_HL(index), (val >> 4) & 0xff); |
826 | val &= 0x0f; | 825 | val &= 0x0f; |
827 | if (index & 1) { | 826 | if (index & 1) { |
828 | val <<= 4; | 827 | val <<= 4; |
829 | val |= w83795_read(client, W83795_REG_FAN_MIN_LSB(index)) | 828 | val |= w83795_read(client, W83795_REG_FAN_MIN_LSB(index)) |
830 | & 0x0f; | 829 | & 0x0f; |
831 | } else { | 830 | } else { |
832 | val |= w83795_read(client, W83795_REG_FAN_MIN_LSB(index)) | 831 | val |= w83795_read(client, W83795_REG_FAN_MIN_LSB(index)) |
833 | & 0xf0; | 832 | & 0xf0; |
834 | } | 833 | } |
835 | w83795_write(client, W83795_REG_FAN_MIN_LSB(index), val & 0xff); | 834 | w83795_write(client, W83795_REG_FAN_MIN_LSB(index), val & 0xff); |
836 | mutex_unlock(&data->update_lock); | 835 | mutex_unlock(&data->update_lock); |
837 | 836 | ||
838 | return count; | 837 | return count; |
839 | } | 838 | } |
840 | 839 | ||
841 | static ssize_t | 840 | static ssize_t |
842 | show_pwm(struct device *dev, struct device_attribute *attr, char *buf) | 841 | show_pwm(struct device *dev, struct device_attribute *attr, char *buf) |
843 | { | 842 | { |
844 | struct w83795_data *data; | 843 | struct w83795_data *data; |
845 | struct sensor_device_attribute_2 *sensor_attr = | 844 | struct sensor_device_attribute_2 *sensor_attr = |
846 | to_sensor_dev_attr_2(attr); | 845 | to_sensor_dev_attr_2(attr); |
847 | int nr = sensor_attr->nr; | 846 | int nr = sensor_attr->nr; |
848 | int index = sensor_attr->index; | 847 | int index = sensor_attr->index; |
849 | unsigned int val; | 848 | unsigned int val; |
850 | 849 | ||
851 | data = nr == PWM_OUTPUT ? w83795_update_device(dev) | 850 | data = nr == PWM_OUTPUT ? w83795_update_device(dev) |
852 | : w83795_update_pwm_config(dev); | 851 | : w83795_update_pwm_config(dev); |
853 | 852 | ||
854 | switch (nr) { | 853 | switch (nr) { |
855 | case PWM_STOP_TIME: | 854 | case PWM_STOP_TIME: |
856 | val = time_from_reg(data->pwm[index][nr]); | 855 | val = time_from_reg(data->pwm[index][nr]); |
857 | break; | 856 | break; |
858 | case PWM_FREQ: | 857 | case PWM_FREQ: |
859 | val = pwm_freq_from_reg(data->pwm[index][nr], data->clkin); | 858 | val = pwm_freq_from_reg(data->pwm[index][nr], data->clkin); |
860 | break; | 859 | break; |
861 | default: | 860 | default: |
862 | val = data->pwm[index][nr]; | 861 | val = data->pwm[index][nr]; |
863 | break; | 862 | break; |
864 | } | 863 | } |
865 | 864 | ||
866 | return sprintf(buf, "%u\n", val); | 865 | return sprintf(buf, "%u\n", val); |
867 | } | 866 | } |
868 | 867 | ||
869 | static ssize_t | 868 | static ssize_t |
870 | store_pwm(struct device *dev, struct device_attribute *attr, | 869 | store_pwm(struct device *dev, struct device_attribute *attr, |
871 | const char *buf, size_t count) | 870 | const char *buf, size_t count) |
872 | { | 871 | { |
873 | struct i2c_client *client = to_i2c_client(dev); | 872 | struct i2c_client *client = to_i2c_client(dev); |
874 | struct w83795_data *data = i2c_get_clientdata(client); | 873 | struct w83795_data *data = i2c_get_clientdata(client); |
875 | struct sensor_device_attribute_2 *sensor_attr = | 874 | struct sensor_device_attribute_2 *sensor_attr = |
876 | to_sensor_dev_attr_2(attr); | 875 | to_sensor_dev_attr_2(attr); |
877 | int nr = sensor_attr->nr; | 876 | int nr = sensor_attr->nr; |
878 | int index = sensor_attr->index; | 877 | int index = sensor_attr->index; |
879 | unsigned long val; | 878 | unsigned long val; |
880 | 879 | ||
881 | if (kstrtoul(buf, 10, &val) < 0) | 880 | if (kstrtoul(buf, 10, &val) < 0) |
882 | return -EINVAL; | 881 | return -EINVAL; |
883 | 882 | ||
884 | mutex_lock(&data->update_lock); | 883 | mutex_lock(&data->update_lock); |
885 | switch (nr) { | 884 | switch (nr) { |
886 | case PWM_STOP_TIME: | 885 | case PWM_STOP_TIME: |
887 | val = time_to_reg(val); | 886 | val = time_to_reg(val); |
888 | break; | 887 | break; |
889 | case PWM_FREQ: | 888 | case PWM_FREQ: |
890 | val = pwm_freq_to_reg(val, data->clkin); | 889 | val = pwm_freq_to_reg(val, data->clkin); |
891 | break; | 890 | break; |
892 | default: | 891 | default: |
893 | val = SENSORS_LIMIT(val, 0, 0xff); | 892 | val = SENSORS_LIMIT(val, 0, 0xff); |
894 | break; | 893 | break; |
895 | } | 894 | } |
896 | w83795_write(client, W83795_REG_PWM(index, nr), val); | 895 | w83795_write(client, W83795_REG_PWM(index, nr), val); |
897 | data->pwm[index][nr] = val; | 896 | data->pwm[index][nr] = val; |
898 | mutex_unlock(&data->update_lock); | 897 | mutex_unlock(&data->update_lock); |
899 | return count; | 898 | return count; |
900 | } | 899 | } |
901 | 900 | ||
902 | static ssize_t | 901 | static ssize_t |
903 | show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) | 902 | show_pwm_enable(struct device *dev, struct device_attribute *attr, char *buf) |
904 | { | 903 | { |
905 | struct sensor_device_attribute_2 *sensor_attr = | 904 | struct sensor_device_attribute_2 *sensor_attr = |
906 | to_sensor_dev_attr_2(attr); | 905 | to_sensor_dev_attr_2(attr); |
907 | struct w83795_data *data = w83795_update_pwm_config(dev); | 906 | struct w83795_data *data = w83795_update_pwm_config(dev); |
908 | int index = sensor_attr->index; | 907 | int index = sensor_attr->index; |
909 | u8 tmp; | 908 | u8 tmp; |
910 | 909 | ||
911 | /* Speed cruise mode */ | 910 | /* Speed cruise mode */ |
912 | if (data->pwm_fcms[0] & (1 << index)) { | 911 | if (data->pwm_fcms[0] & (1 << index)) { |
913 | tmp = 2; | 912 | tmp = 2; |
914 | goto out; | 913 | goto out; |
915 | } | 914 | } |
916 | /* Thermal cruise or SmartFan IV mode */ | 915 | /* Thermal cruise or SmartFan IV mode */ |
917 | for (tmp = 0; tmp < 6; tmp++) { | 916 | for (tmp = 0; tmp < 6; tmp++) { |
918 | if (data->pwm_tfmr[tmp] & (1 << index)) { | 917 | if (data->pwm_tfmr[tmp] & (1 << index)) { |
919 | tmp = 3; | 918 | tmp = 3; |
920 | goto out; | 919 | goto out; |
921 | } | 920 | } |
922 | } | 921 | } |
923 | /* Manual mode */ | 922 | /* Manual mode */ |
924 | tmp = 1; | 923 | tmp = 1; |
925 | 924 | ||
926 | out: | 925 | out: |
927 | return sprintf(buf, "%u\n", tmp); | 926 | return sprintf(buf, "%u\n", tmp); |
928 | } | 927 | } |
929 | 928 | ||
930 | static ssize_t | 929 | static ssize_t |
931 | store_pwm_enable(struct device *dev, struct device_attribute *attr, | 930 | store_pwm_enable(struct device *dev, struct device_attribute *attr, |
932 | const char *buf, size_t count) | 931 | const char *buf, size_t count) |
933 | { | 932 | { |
934 | struct i2c_client *client = to_i2c_client(dev); | 933 | struct i2c_client *client = to_i2c_client(dev); |
935 | struct w83795_data *data = w83795_update_pwm_config(dev); | 934 | struct w83795_data *data = w83795_update_pwm_config(dev); |
936 | struct sensor_device_attribute_2 *sensor_attr = | 935 | struct sensor_device_attribute_2 *sensor_attr = |
937 | to_sensor_dev_attr_2(attr); | 936 | to_sensor_dev_attr_2(attr); |
938 | int index = sensor_attr->index; | 937 | int index = sensor_attr->index; |
939 | unsigned long val; | 938 | unsigned long val; |
940 | int i; | 939 | int i; |
941 | 940 | ||
942 | if (kstrtoul(buf, 10, &val) < 0) | 941 | if (kstrtoul(buf, 10, &val) < 0) |
943 | return -EINVAL; | 942 | return -EINVAL; |
944 | if (val < 1 || val > 2) | 943 | if (val < 1 || val > 2) |
945 | return -EINVAL; | 944 | return -EINVAL; |
946 | 945 | ||
947 | #ifndef CONFIG_SENSORS_W83795_FANCTRL | 946 | #ifndef CONFIG_SENSORS_W83795_FANCTRL |
948 | if (val > 1) { | 947 | if (val > 1) { |
949 | dev_warn(dev, "Automatic fan speed control support disabled\n"); | 948 | dev_warn(dev, "Automatic fan speed control support disabled\n"); |
950 | dev_warn(dev, "Build with CONFIG_SENSORS_W83795_FANCTRL=y if you want it\n"); | 949 | dev_warn(dev, "Build with CONFIG_SENSORS_W83795_FANCTRL=y if you want it\n"); |
951 | return -EOPNOTSUPP; | 950 | return -EOPNOTSUPP; |
952 | } | 951 | } |
953 | #endif | 952 | #endif |
954 | 953 | ||
955 | mutex_lock(&data->update_lock); | 954 | mutex_lock(&data->update_lock); |
956 | switch (val) { | 955 | switch (val) { |
957 | case 1: | 956 | case 1: |
958 | /* Clear speed cruise mode bits */ | 957 | /* Clear speed cruise mode bits */ |
959 | data->pwm_fcms[0] &= ~(1 << index); | 958 | data->pwm_fcms[0] &= ~(1 << index); |
960 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); | 959 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); |
961 | /* Clear thermal cruise mode bits */ | 960 | /* Clear thermal cruise mode bits */ |
962 | for (i = 0; i < 6; i++) { | 961 | for (i = 0; i < 6; i++) { |
963 | data->pwm_tfmr[i] &= ~(1 << index); | 962 | data->pwm_tfmr[i] &= ~(1 << index); |
964 | w83795_write(client, W83795_REG_TFMR(i), | 963 | w83795_write(client, W83795_REG_TFMR(i), |
965 | data->pwm_tfmr[i]); | 964 | data->pwm_tfmr[i]); |
966 | } | 965 | } |
967 | break; | 966 | break; |
968 | case 2: | 967 | case 2: |
969 | data->pwm_fcms[0] |= (1 << index); | 968 | data->pwm_fcms[0] |= (1 << index); |
970 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); | 969 | w83795_write(client, W83795_REG_FCMS1, data->pwm_fcms[0]); |
971 | break; | 970 | break; |
972 | } | 971 | } |
973 | mutex_unlock(&data->update_lock); | 972 | mutex_unlock(&data->update_lock); |
974 | return count; | 973 | return count; |
975 | } | 974 | } |
976 | 975 | ||
977 | static ssize_t | 976 | static ssize_t |
978 | show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) | 977 | show_pwm_mode(struct device *dev, struct device_attribute *attr, char *buf) |
979 | { | 978 | { |
980 | struct w83795_data *data = w83795_update_pwm_config(dev); | 979 | struct w83795_data *data = w83795_update_pwm_config(dev); |
981 | int index = to_sensor_dev_attr_2(attr)->index; | 980 | int index = to_sensor_dev_attr_2(attr)->index; |
982 | unsigned int mode; | 981 | unsigned int mode; |
983 | 982 | ||
984 | if (data->pwm_fomc & (1 << index)) | 983 | if (data->pwm_fomc & (1 << index)) |
985 | mode = 0; /* DC */ | 984 | mode = 0; /* DC */ |
986 | else | 985 | else |
987 | mode = 1; /* PWM */ | 986 | mode = 1; /* PWM */ |
988 | 987 | ||
989 | return sprintf(buf, "%u\n", mode); | 988 | return sprintf(buf, "%u\n", mode); |
990 | } | 989 | } |
991 | 990 | ||
992 | /* | 991 | /* |
993 | * Check whether a given temperature source can ever be useful. | 992 | * Check whether a given temperature source can ever be useful. |
994 | * Returns the number of selectable temperature channels which are | 993 | * Returns the number of selectable temperature channels which are |
995 | * enabled. | 994 | * enabled. |
996 | */ | 995 | */ |
997 | static int w83795_tss_useful(const struct w83795_data *data, int tsrc) | 996 | static int w83795_tss_useful(const struct w83795_data *data, int tsrc) |
998 | { | 997 | { |
999 | int useful = 0, i; | 998 | int useful = 0, i; |
1000 | 999 | ||
1001 | for (i = 0; i < 4; i++) { | 1000 | for (i = 0; i < 4; i++) { |
1002 | if (tss_map[i][tsrc] == TSS_MAP_RESERVED) | 1001 | if (tss_map[i][tsrc] == TSS_MAP_RESERVED) |
1003 | continue; | 1002 | continue; |
1004 | if (tss_map[i][tsrc] < 6) /* Analog */ | 1003 | if (tss_map[i][tsrc] < 6) /* Analog */ |
1005 | useful += (data->has_temp >> tss_map[i][tsrc]) & 1; | 1004 | useful += (data->has_temp >> tss_map[i][tsrc]) & 1; |
1006 | else /* Digital */ | 1005 | else /* Digital */ |
1007 | useful += (data->has_dts >> (tss_map[i][tsrc] - 6)) & 1; | 1006 | useful += (data->has_dts >> (tss_map[i][tsrc] - 6)) & 1; |
1008 | } | 1007 | } |
1009 | 1008 | ||
1010 | return useful; | 1009 | return useful; |
1011 | } | 1010 | } |
1012 | 1011 | ||
1013 | static ssize_t | 1012 | static ssize_t |
1014 | show_temp_src(struct device *dev, struct device_attribute *attr, char *buf) | 1013 | show_temp_src(struct device *dev, struct device_attribute *attr, char *buf) |
1015 | { | 1014 | { |
1016 | struct sensor_device_attribute_2 *sensor_attr = | 1015 | struct sensor_device_attribute_2 *sensor_attr = |
1017 | to_sensor_dev_attr_2(attr); | 1016 | to_sensor_dev_attr_2(attr); |
1018 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1017 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1019 | int index = sensor_attr->index; | 1018 | int index = sensor_attr->index; |
1020 | u8 tmp = data->temp_src[index / 2]; | 1019 | u8 tmp = data->temp_src[index / 2]; |
1021 | 1020 | ||
1022 | if (index & 1) | 1021 | if (index & 1) |
1023 | tmp >>= 4; /* Pick high nibble */ | 1022 | tmp >>= 4; /* Pick high nibble */ |
1024 | else | 1023 | else |
1025 | tmp &= 0x0f; /* Pick low nibble */ | 1024 | tmp &= 0x0f; /* Pick low nibble */ |
1026 | 1025 | ||
1027 | /* Look-up the actual temperature channel number */ | 1026 | /* Look-up the actual temperature channel number */ |
1028 | if (tmp >= 4 || tss_map[tmp][index] == TSS_MAP_RESERVED) | 1027 | if (tmp >= 4 || tss_map[tmp][index] == TSS_MAP_RESERVED) |
1029 | return -EINVAL; /* Shouldn't happen */ | 1028 | return -EINVAL; /* Shouldn't happen */ |
1030 | 1029 | ||
1031 | return sprintf(buf, "%u\n", (unsigned int)tss_map[tmp][index] + 1); | 1030 | return sprintf(buf, "%u\n", (unsigned int)tss_map[tmp][index] + 1); |
1032 | } | 1031 | } |
1033 | 1032 | ||
1034 | static ssize_t | 1033 | static ssize_t |
1035 | store_temp_src(struct device *dev, struct device_attribute *attr, | 1034 | store_temp_src(struct device *dev, struct device_attribute *attr, |
1036 | const char *buf, size_t count) | 1035 | const char *buf, size_t count) |
1037 | { | 1036 | { |
1038 | struct i2c_client *client = to_i2c_client(dev); | 1037 | struct i2c_client *client = to_i2c_client(dev); |
1039 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1038 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1040 | struct sensor_device_attribute_2 *sensor_attr = | 1039 | struct sensor_device_attribute_2 *sensor_attr = |
1041 | to_sensor_dev_attr_2(attr); | 1040 | to_sensor_dev_attr_2(attr); |
1042 | int index = sensor_attr->index; | 1041 | int index = sensor_attr->index; |
1043 | int tmp; | 1042 | int tmp; |
1044 | unsigned long channel; | 1043 | unsigned long channel; |
1045 | u8 val = index / 2; | 1044 | u8 val = index / 2; |
1046 | 1045 | ||
1047 | if (kstrtoul(buf, 10, &channel) < 0 || | 1046 | if (kstrtoul(buf, 10, &channel) < 0 || |
1048 | channel < 1 || channel > 14) | 1047 | channel < 1 || channel > 14) |
1049 | return -EINVAL; | 1048 | return -EINVAL; |
1050 | 1049 | ||
1051 | /* Check if request can be fulfilled */ | 1050 | /* Check if request can be fulfilled */ |
1052 | for (tmp = 0; tmp < 4; tmp++) { | 1051 | for (tmp = 0; tmp < 4; tmp++) { |
1053 | if (tss_map[tmp][index] == channel - 1) | 1052 | if (tss_map[tmp][index] == channel - 1) |
1054 | break; | 1053 | break; |
1055 | } | 1054 | } |
1056 | if (tmp == 4) /* No match */ | 1055 | if (tmp == 4) /* No match */ |
1057 | return -EINVAL; | 1056 | return -EINVAL; |
1058 | 1057 | ||
1059 | mutex_lock(&data->update_lock); | 1058 | mutex_lock(&data->update_lock); |
1060 | if (index & 1) { | 1059 | if (index & 1) { |
1061 | tmp <<= 4; | 1060 | tmp <<= 4; |
1062 | data->temp_src[val] &= 0x0f; | 1061 | data->temp_src[val] &= 0x0f; |
1063 | } else { | 1062 | } else { |
1064 | data->temp_src[val] &= 0xf0; | 1063 | data->temp_src[val] &= 0xf0; |
1065 | } | 1064 | } |
1066 | data->temp_src[val] |= tmp; | 1065 | data->temp_src[val] |= tmp; |
1067 | w83795_write(client, W83795_REG_TSS(val), data->temp_src[val]); | 1066 | w83795_write(client, W83795_REG_TSS(val), data->temp_src[val]); |
1068 | mutex_unlock(&data->update_lock); | 1067 | mutex_unlock(&data->update_lock); |
1069 | 1068 | ||
1070 | return count; | 1069 | return count; |
1071 | } | 1070 | } |
1072 | 1071 | ||
1073 | #define TEMP_PWM_ENABLE 0 | 1072 | #define TEMP_PWM_ENABLE 0 |
1074 | #define TEMP_PWM_FAN_MAP 1 | 1073 | #define TEMP_PWM_FAN_MAP 1 |
1075 | static ssize_t | 1074 | static ssize_t |
1076 | show_temp_pwm_enable(struct device *dev, struct device_attribute *attr, | 1075 | show_temp_pwm_enable(struct device *dev, struct device_attribute *attr, |
1077 | char *buf) | 1076 | char *buf) |
1078 | { | 1077 | { |
1079 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1078 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1080 | struct sensor_device_attribute_2 *sensor_attr = | 1079 | struct sensor_device_attribute_2 *sensor_attr = |
1081 | to_sensor_dev_attr_2(attr); | 1080 | to_sensor_dev_attr_2(attr); |
1082 | int nr = sensor_attr->nr; | 1081 | int nr = sensor_attr->nr; |
1083 | int index = sensor_attr->index; | 1082 | int index = sensor_attr->index; |
1084 | u8 tmp = 0xff; | 1083 | u8 tmp = 0xff; |
1085 | 1084 | ||
1086 | switch (nr) { | 1085 | switch (nr) { |
1087 | case TEMP_PWM_ENABLE: | 1086 | case TEMP_PWM_ENABLE: |
1088 | tmp = (data->pwm_fcms[1] >> index) & 1; | 1087 | tmp = (data->pwm_fcms[1] >> index) & 1; |
1089 | if (tmp) | 1088 | if (tmp) |
1090 | tmp = 4; | 1089 | tmp = 4; |
1091 | else | 1090 | else |
1092 | tmp = 3; | 1091 | tmp = 3; |
1093 | break; | 1092 | break; |
1094 | case TEMP_PWM_FAN_MAP: | 1093 | case TEMP_PWM_FAN_MAP: |
1095 | tmp = data->pwm_tfmr[index]; | 1094 | tmp = data->pwm_tfmr[index]; |
1096 | break; | 1095 | break; |
1097 | } | 1096 | } |
1098 | 1097 | ||
1099 | return sprintf(buf, "%u\n", tmp); | 1098 | return sprintf(buf, "%u\n", tmp); |
1100 | } | 1099 | } |
1101 | 1100 | ||
1102 | static ssize_t | 1101 | static ssize_t |
1103 | store_temp_pwm_enable(struct device *dev, struct device_attribute *attr, | 1102 | store_temp_pwm_enable(struct device *dev, struct device_attribute *attr, |
1104 | const char *buf, size_t count) | 1103 | const char *buf, size_t count) |
1105 | { | 1104 | { |
1106 | struct i2c_client *client = to_i2c_client(dev); | 1105 | struct i2c_client *client = to_i2c_client(dev); |
1107 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1106 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1108 | struct sensor_device_attribute_2 *sensor_attr = | 1107 | struct sensor_device_attribute_2 *sensor_attr = |
1109 | to_sensor_dev_attr_2(attr); | 1108 | to_sensor_dev_attr_2(attr); |
1110 | int nr = sensor_attr->nr; | 1109 | int nr = sensor_attr->nr; |
1111 | int index = sensor_attr->index; | 1110 | int index = sensor_attr->index; |
1112 | unsigned long tmp; | 1111 | unsigned long tmp; |
1113 | 1112 | ||
1114 | if (kstrtoul(buf, 10, &tmp) < 0) | 1113 | if (kstrtoul(buf, 10, &tmp) < 0) |
1115 | return -EINVAL; | 1114 | return -EINVAL; |
1116 | 1115 | ||
1117 | switch (nr) { | 1116 | switch (nr) { |
1118 | case TEMP_PWM_ENABLE: | 1117 | case TEMP_PWM_ENABLE: |
1119 | if (tmp != 3 && tmp != 4) | 1118 | if (tmp != 3 && tmp != 4) |
1120 | return -EINVAL; | 1119 | return -EINVAL; |
1121 | tmp -= 3; | 1120 | tmp -= 3; |
1122 | mutex_lock(&data->update_lock); | 1121 | mutex_lock(&data->update_lock); |
1123 | data->pwm_fcms[1] &= ~(1 << index); | 1122 | data->pwm_fcms[1] &= ~(1 << index); |
1124 | data->pwm_fcms[1] |= tmp << index; | 1123 | data->pwm_fcms[1] |= tmp << index; |
1125 | w83795_write(client, W83795_REG_FCMS2, data->pwm_fcms[1]); | 1124 | w83795_write(client, W83795_REG_FCMS2, data->pwm_fcms[1]); |
1126 | mutex_unlock(&data->update_lock); | 1125 | mutex_unlock(&data->update_lock); |
1127 | break; | 1126 | break; |
1128 | case TEMP_PWM_FAN_MAP: | 1127 | case TEMP_PWM_FAN_MAP: |
1129 | mutex_lock(&data->update_lock); | 1128 | mutex_lock(&data->update_lock); |
1130 | tmp = SENSORS_LIMIT(tmp, 0, 0xff); | 1129 | tmp = SENSORS_LIMIT(tmp, 0, 0xff); |
1131 | w83795_write(client, W83795_REG_TFMR(index), tmp); | 1130 | w83795_write(client, W83795_REG_TFMR(index), tmp); |
1132 | data->pwm_tfmr[index] = tmp; | 1131 | data->pwm_tfmr[index] = tmp; |
1133 | mutex_unlock(&data->update_lock); | 1132 | mutex_unlock(&data->update_lock); |
1134 | break; | 1133 | break; |
1135 | } | 1134 | } |
1136 | return count; | 1135 | return count; |
1137 | } | 1136 | } |
1138 | 1137 | ||
1139 | #define FANIN_TARGET 0 | 1138 | #define FANIN_TARGET 0 |
1140 | #define FANIN_TOL 1 | 1139 | #define FANIN_TOL 1 |
1141 | static ssize_t | 1140 | static ssize_t |
1142 | show_fanin(struct device *dev, struct device_attribute *attr, char *buf) | 1141 | show_fanin(struct device *dev, struct device_attribute *attr, char *buf) |
1143 | { | 1142 | { |
1144 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1143 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1145 | struct sensor_device_attribute_2 *sensor_attr = | 1144 | struct sensor_device_attribute_2 *sensor_attr = |
1146 | to_sensor_dev_attr_2(attr); | 1145 | to_sensor_dev_attr_2(attr); |
1147 | int nr = sensor_attr->nr; | 1146 | int nr = sensor_attr->nr; |
1148 | int index = sensor_attr->index; | 1147 | int index = sensor_attr->index; |
1149 | u16 tmp = 0; | 1148 | u16 tmp = 0; |
1150 | 1149 | ||
1151 | switch (nr) { | 1150 | switch (nr) { |
1152 | case FANIN_TARGET: | 1151 | case FANIN_TARGET: |
1153 | tmp = fan_from_reg(data->target_speed[index]); | 1152 | tmp = fan_from_reg(data->target_speed[index]); |
1154 | break; | 1153 | break; |
1155 | case FANIN_TOL: | 1154 | case FANIN_TOL: |
1156 | tmp = data->tol_speed; | 1155 | tmp = data->tol_speed; |
1157 | break; | 1156 | break; |
1158 | } | 1157 | } |
1159 | 1158 | ||
1160 | return sprintf(buf, "%u\n", tmp); | 1159 | return sprintf(buf, "%u\n", tmp); |
1161 | } | 1160 | } |
1162 | 1161 | ||
1163 | static ssize_t | 1162 | static ssize_t |
1164 | store_fanin(struct device *dev, struct device_attribute *attr, | 1163 | store_fanin(struct device *dev, struct device_attribute *attr, |
1165 | const char *buf, size_t count) | 1164 | const char *buf, size_t count) |
1166 | { | 1165 | { |
1167 | struct i2c_client *client = to_i2c_client(dev); | 1166 | struct i2c_client *client = to_i2c_client(dev); |
1168 | struct w83795_data *data = i2c_get_clientdata(client); | 1167 | struct w83795_data *data = i2c_get_clientdata(client); |
1169 | struct sensor_device_attribute_2 *sensor_attr = | 1168 | struct sensor_device_attribute_2 *sensor_attr = |
1170 | to_sensor_dev_attr_2(attr); | 1169 | to_sensor_dev_attr_2(attr); |
1171 | int nr = sensor_attr->nr; | 1170 | int nr = sensor_attr->nr; |
1172 | int index = sensor_attr->index; | 1171 | int index = sensor_attr->index; |
1173 | unsigned long val; | 1172 | unsigned long val; |
1174 | 1173 | ||
1175 | if (kstrtoul(buf, 10, &val) < 0) | 1174 | if (kstrtoul(buf, 10, &val) < 0) |
1176 | return -EINVAL; | 1175 | return -EINVAL; |
1177 | 1176 | ||
1178 | mutex_lock(&data->update_lock); | 1177 | mutex_lock(&data->update_lock); |
1179 | switch (nr) { | 1178 | switch (nr) { |
1180 | case FANIN_TARGET: | 1179 | case FANIN_TARGET: |
1181 | val = fan_to_reg(SENSORS_LIMIT(val, 0, 0xfff)); | 1180 | val = fan_to_reg(SENSORS_LIMIT(val, 0, 0xfff)); |
1182 | w83795_write(client, W83795_REG_FTSH(index), val >> 4); | 1181 | w83795_write(client, W83795_REG_FTSH(index), val >> 4); |
1183 | w83795_write(client, W83795_REG_FTSL(index), (val << 4) & 0xf0); | 1182 | w83795_write(client, W83795_REG_FTSL(index), (val << 4) & 0xf0); |
1184 | data->target_speed[index] = val; | 1183 | data->target_speed[index] = val; |
1185 | break; | 1184 | break; |
1186 | case FANIN_TOL: | 1185 | case FANIN_TOL: |
1187 | val = SENSORS_LIMIT(val, 0, 0x3f); | 1186 | val = SENSORS_LIMIT(val, 0, 0x3f); |
1188 | w83795_write(client, W83795_REG_TFTS, val); | 1187 | w83795_write(client, W83795_REG_TFTS, val); |
1189 | data->tol_speed = val; | 1188 | data->tol_speed = val; |
1190 | break; | 1189 | break; |
1191 | } | 1190 | } |
1192 | mutex_unlock(&data->update_lock); | 1191 | mutex_unlock(&data->update_lock); |
1193 | 1192 | ||
1194 | return count; | 1193 | return count; |
1195 | } | 1194 | } |
1196 | 1195 | ||
1197 | 1196 | ||
1198 | static ssize_t | 1197 | static ssize_t |
1199 | show_temp_pwm(struct device *dev, struct device_attribute *attr, char *buf) | 1198 | show_temp_pwm(struct device *dev, struct device_attribute *attr, char *buf) |
1200 | { | 1199 | { |
1201 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1200 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1202 | struct sensor_device_attribute_2 *sensor_attr = | 1201 | struct sensor_device_attribute_2 *sensor_attr = |
1203 | to_sensor_dev_attr_2(attr); | 1202 | to_sensor_dev_attr_2(attr); |
1204 | int nr = sensor_attr->nr; | 1203 | int nr = sensor_attr->nr; |
1205 | int index = sensor_attr->index; | 1204 | int index = sensor_attr->index; |
1206 | long tmp = temp_from_reg(data->pwm_temp[index][nr]); | 1205 | long tmp = temp_from_reg(data->pwm_temp[index][nr]); |
1207 | 1206 | ||
1208 | return sprintf(buf, "%ld\n", tmp); | 1207 | return sprintf(buf, "%ld\n", tmp); |
1209 | } | 1208 | } |
1210 | 1209 | ||
1211 | static ssize_t | 1210 | static ssize_t |
1212 | store_temp_pwm(struct device *dev, struct device_attribute *attr, | 1211 | store_temp_pwm(struct device *dev, struct device_attribute *attr, |
1213 | const char *buf, size_t count) | 1212 | const char *buf, size_t count) |
1214 | { | 1213 | { |
1215 | struct i2c_client *client = to_i2c_client(dev); | 1214 | struct i2c_client *client = to_i2c_client(dev); |
1216 | struct w83795_data *data = i2c_get_clientdata(client); | 1215 | struct w83795_data *data = i2c_get_clientdata(client); |
1217 | struct sensor_device_attribute_2 *sensor_attr = | 1216 | struct sensor_device_attribute_2 *sensor_attr = |
1218 | to_sensor_dev_attr_2(attr); | 1217 | to_sensor_dev_attr_2(attr); |
1219 | int nr = sensor_attr->nr; | 1218 | int nr = sensor_attr->nr; |
1220 | int index = sensor_attr->index; | 1219 | int index = sensor_attr->index; |
1221 | unsigned long val; | 1220 | unsigned long val; |
1222 | u8 tmp; | 1221 | u8 tmp; |
1223 | 1222 | ||
1224 | if (kstrtoul(buf, 10, &val) < 0) | 1223 | if (kstrtoul(buf, 10, &val) < 0) |
1225 | return -EINVAL; | 1224 | return -EINVAL; |
1226 | val /= 1000; | 1225 | val /= 1000; |
1227 | 1226 | ||
1228 | mutex_lock(&data->update_lock); | 1227 | mutex_lock(&data->update_lock); |
1229 | switch (nr) { | 1228 | switch (nr) { |
1230 | case TEMP_PWM_TTTI: | 1229 | case TEMP_PWM_TTTI: |
1231 | val = SENSORS_LIMIT(val, 0, 0x7f); | 1230 | val = SENSORS_LIMIT(val, 0, 0x7f); |
1232 | w83795_write(client, W83795_REG_TTTI(index), val); | 1231 | w83795_write(client, W83795_REG_TTTI(index), val); |
1233 | break; | 1232 | break; |
1234 | case TEMP_PWM_CTFS: | 1233 | case TEMP_PWM_CTFS: |
1235 | val = SENSORS_LIMIT(val, 0, 0x7f); | 1234 | val = SENSORS_LIMIT(val, 0, 0x7f); |
1236 | w83795_write(client, W83795_REG_CTFS(index), val); | 1235 | w83795_write(client, W83795_REG_CTFS(index), val); |
1237 | break; | 1236 | break; |
1238 | case TEMP_PWM_HCT: | 1237 | case TEMP_PWM_HCT: |
1239 | val = SENSORS_LIMIT(val, 0, 0x0f); | 1238 | val = SENSORS_LIMIT(val, 0, 0x0f); |
1240 | tmp = w83795_read(client, W83795_REG_HT(index)); | 1239 | tmp = w83795_read(client, W83795_REG_HT(index)); |
1241 | tmp &= 0x0f; | 1240 | tmp &= 0x0f; |
1242 | tmp |= (val << 4) & 0xf0; | 1241 | tmp |= (val << 4) & 0xf0; |
1243 | w83795_write(client, W83795_REG_HT(index), tmp); | 1242 | w83795_write(client, W83795_REG_HT(index), tmp); |
1244 | break; | 1243 | break; |
1245 | case TEMP_PWM_HOT: | 1244 | case TEMP_PWM_HOT: |
1246 | val = SENSORS_LIMIT(val, 0, 0x0f); | 1245 | val = SENSORS_LIMIT(val, 0, 0x0f); |
1247 | tmp = w83795_read(client, W83795_REG_HT(index)); | 1246 | tmp = w83795_read(client, W83795_REG_HT(index)); |
1248 | tmp &= 0xf0; | 1247 | tmp &= 0xf0; |
1249 | tmp |= val & 0x0f; | 1248 | tmp |= val & 0x0f; |
1250 | w83795_write(client, W83795_REG_HT(index), tmp); | 1249 | w83795_write(client, W83795_REG_HT(index), tmp); |
1251 | break; | 1250 | break; |
1252 | } | 1251 | } |
1253 | data->pwm_temp[index][nr] = val; | 1252 | data->pwm_temp[index][nr] = val; |
1254 | mutex_unlock(&data->update_lock); | 1253 | mutex_unlock(&data->update_lock); |
1255 | 1254 | ||
1256 | return count; | 1255 | return count; |
1257 | } | 1256 | } |
1258 | 1257 | ||
1259 | static ssize_t | 1258 | static ssize_t |
1260 | show_sf4_pwm(struct device *dev, struct device_attribute *attr, char *buf) | 1259 | show_sf4_pwm(struct device *dev, struct device_attribute *attr, char *buf) |
1261 | { | 1260 | { |
1262 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1261 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1263 | struct sensor_device_attribute_2 *sensor_attr = | 1262 | struct sensor_device_attribute_2 *sensor_attr = |
1264 | to_sensor_dev_attr_2(attr); | 1263 | to_sensor_dev_attr_2(attr); |
1265 | int nr = sensor_attr->nr; | 1264 | int nr = sensor_attr->nr; |
1266 | int index = sensor_attr->index; | 1265 | int index = sensor_attr->index; |
1267 | 1266 | ||
1268 | return sprintf(buf, "%u\n", data->sf4_reg[index][SF4_PWM][nr]); | 1267 | return sprintf(buf, "%u\n", data->sf4_reg[index][SF4_PWM][nr]); |
1269 | } | 1268 | } |
1270 | 1269 | ||
1271 | static ssize_t | 1270 | static ssize_t |
1272 | store_sf4_pwm(struct device *dev, struct device_attribute *attr, | 1271 | store_sf4_pwm(struct device *dev, struct device_attribute *attr, |
1273 | const char *buf, size_t count) | 1272 | const char *buf, size_t count) |
1274 | { | 1273 | { |
1275 | struct i2c_client *client = to_i2c_client(dev); | 1274 | struct i2c_client *client = to_i2c_client(dev); |
1276 | struct w83795_data *data = i2c_get_clientdata(client); | 1275 | struct w83795_data *data = i2c_get_clientdata(client); |
1277 | struct sensor_device_attribute_2 *sensor_attr = | 1276 | struct sensor_device_attribute_2 *sensor_attr = |
1278 | to_sensor_dev_attr_2(attr); | 1277 | to_sensor_dev_attr_2(attr); |
1279 | int nr = sensor_attr->nr; | 1278 | int nr = sensor_attr->nr; |
1280 | int index = sensor_attr->index; | 1279 | int index = sensor_attr->index; |
1281 | unsigned long val; | 1280 | unsigned long val; |
1282 | 1281 | ||
1283 | if (kstrtoul(buf, 10, &val) < 0) | 1282 | if (kstrtoul(buf, 10, &val) < 0) |
1284 | return -EINVAL; | 1283 | return -EINVAL; |
1285 | 1284 | ||
1286 | mutex_lock(&data->update_lock); | 1285 | mutex_lock(&data->update_lock); |
1287 | w83795_write(client, W83795_REG_SF4_PWM(index, nr), val); | 1286 | w83795_write(client, W83795_REG_SF4_PWM(index, nr), val); |
1288 | data->sf4_reg[index][SF4_PWM][nr] = val; | 1287 | data->sf4_reg[index][SF4_PWM][nr] = val; |
1289 | mutex_unlock(&data->update_lock); | 1288 | mutex_unlock(&data->update_lock); |
1290 | 1289 | ||
1291 | return count; | 1290 | return count; |
1292 | } | 1291 | } |
1293 | 1292 | ||
1294 | static ssize_t | 1293 | static ssize_t |
1295 | show_sf4_temp(struct device *dev, struct device_attribute *attr, char *buf) | 1294 | show_sf4_temp(struct device *dev, struct device_attribute *attr, char *buf) |
1296 | { | 1295 | { |
1297 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1296 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1298 | struct sensor_device_attribute_2 *sensor_attr = | 1297 | struct sensor_device_attribute_2 *sensor_attr = |
1299 | to_sensor_dev_attr_2(attr); | 1298 | to_sensor_dev_attr_2(attr); |
1300 | int nr = sensor_attr->nr; | 1299 | int nr = sensor_attr->nr; |
1301 | int index = sensor_attr->index; | 1300 | int index = sensor_attr->index; |
1302 | 1301 | ||
1303 | return sprintf(buf, "%u\n", | 1302 | return sprintf(buf, "%u\n", |
1304 | (data->sf4_reg[index][SF4_TEMP][nr]) * 1000); | 1303 | (data->sf4_reg[index][SF4_TEMP][nr]) * 1000); |
1305 | } | 1304 | } |
1306 | 1305 | ||
1307 | static ssize_t | 1306 | static ssize_t |
1308 | store_sf4_temp(struct device *dev, struct device_attribute *attr, | 1307 | store_sf4_temp(struct device *dev, struct device_attribute *attr, |
1309 | const char *buf, size_t count) | 1308 | const char *buf, size_t count) |
1310 | { | 1309 | { |
1311 | struct i2c_client *client = to_i2c_client(dev); | 1310 | struct i2c_client *client = to_i2c_client(dev); |
1312 | struct w83795_data *data = i2c_get_clientdata(client); | 1311 | struct w83795_data *data = i2c_get_clientdata(client); |
1313 | struct sensor_device_attribute_2 *sensor_attr = | 1312 | struct sensor_device_attribute_2 *sensor_attr = |
1314 | to_sensor_dev_attr_2(attr); | 1313 | to_sensor_dev_attr_2(attr); |
1315 | int nr = sensor_attr->nr; | 1314 | int nr = sensor_attr->nr; |
1316 | int index = sensor_attr->index; | 1315 | int index = sensor_attr->index; |
1317 | unsigned long val; | 1316 | unsigned long val; |
1318 | 1317 | ||
1319 | if (kstrtoul(buf, 10, &val) < 0) | 1318 | if (kstrtoul(buf, 10, &val) < 0) |
1320 | return -EINVAL; | 1319 | return -EINVAL; |
1321 | val /= 1000; | 1320 | val /= 1000; |
1322 | 1321 | ||
1323 | mutex_lock(&data->update_lock); | 1322 | mutex_lock(&data->update_lock); |
1324 | w83795_write(client, W83795_REG_SF4_TEMP(index, nr), val); | 1323 | w83795_write(client, W83795_REG_SF4_TEMP(index, nr), val); |
1325 | data->sf4_reg[index][SF4_TEMP][nr] = val; | 1324 | data->sf4_reg[index][SF4_TEMP][nr] = val; |
1326 | mutex_unlock(&data->update_lock); | 1325 | mutex_unlock(&data->update_lock); |
1327 | 1326 | ||
1328 | return count; | 1327 | return count; |
1329 | } | 1328 | } |
1330 | 1329 | ||
1331 | 1330 | ||
1332 | static ssize_t | 1331 | static ssize_t |
1333 | show_temp(struct device *dev, struct device_attribute *attr, char *buf) | 1332 | show_temp(struct device *dev, struct device_attribute *attr, char *buf) |
1334 | { | 1333 | { |
1335 | struct sensor_device_attribute_2 *sensor_attr = | 1334 | struct sensor_device_attribute_2 *sensor_attr = |
1336 | to_sensor_dev_attr_2(attr); | 1335 | to_sensor_dev_attr_2(attr); |
1337 | int nr = sensor_attr->nr; | 1336 | int nr = sensor_attr->nr; |
1338 | int index = sensor_attr->index; | 1337 | int index = sensor_attr->index; |
1339 | struct w83795_data *data = w83795_update_device(dev); | 1338 | struct w83795_data *data = w83795_update_device(dev); |
1340 | long temp = temp_from_reg(data->temp[index][nr]); | 1339 | long temp = temp_from_reg(data->temp[index][nr]); |
1341 | 1340 | ||
1342 | if (nr == TEMP_READ) | 1341 | if (nr == TEMP_READ) |
1343 | temp += (data->temp_read_vrlsb[index] >> 6) * 250; | 1342 | temp += (data->temp_read_vrlsb[index] >> 6) * 250; |
1344 | return sprintf(buf, "%ld\n", temp); | 1343 | return sprintf(buf, "%ld\n", temp); |
1345 | } | 1344 | } |
1346 | 1345 | ||
1347 | static ssize_t | 1346 | static ssize_t |
1348 | store_temp(struct device *dev, struct device_attribute *attr, | 1347 | store_temp(struct device *dev, struct device_attribute *attr, |
1349 | const char *buf, size_t count) | 1348 | const char *buf, size_t count) |
1350 | { | 1349 | { |
1351 | struct sensor_device_attribute_2 *sensor_attr = | 1350 | struct sensor_device_attribute_2 *sensor_attr = |
1352 | to_sensor_dev_attr_2(attr); | 1351 | to_sensor_dev_attr_2(attr); |
1353 | int nr = sensor_attr->nr; | 1352 | int nr = sensor_attr->nr; |
1354 | int index = sensor_attr->index; | 1353 | int index = sensor_attr->index; |
1355 | struct i2c_client *client = to_i2c_client(dev); | 1354 | struct i2c_client *client = to_i2c_client(dev); |
1356 | struct w83795_data *data = i2c_get_clientdata(client); | 1355 | struct w83795_data *data = i2c_get_clientdata(client); |
1357 | long tmp; | 1356 | long tmp; |
1358 | 1357 | ||
1359 | if (kstrtol(buf, 10, &tmp) < 0) | 1358 | if (kstrtol(buf, 10, &tmp) < 0) |
1360 | return -EINVAL; | 1359 | return -EINVAL; |
1361 | 1360 | ||
1362 | mutex_lock(&data->update_lock); | 1361 | mutex_lock(&data->update_lock); |
1363 | data->temp[index][nr] = temp_to_reg(tmp, -128, 127); | 1362 | data->temp[index][nr] = temp_to_reg(tmp, -128, 127); |
1364 | w83795_write(client, W83795_REG_TEMP[index][nr], data->temp[index][nr]); | 1363 | w83795_write(client, W83795_REG_TEMP[index][nr], data->temp[index][nr]); |
1365 | mutex_unlock(&data->update_lock); | 1364 | mutex_unlock(&data->update_lock); |
1366 | return count; | 1365 | return count; |
1367 | } | 1366 | } |
1368 | 1367 | ||
1369 | 1368 | ||
1370 | static ssize_t | 1369 | static ssize_t |
1371 | show_dts_mode(struct device *dev, struct device_attribute *attr, char *buf) | 1370 | show_dts_mode(struct device *dev, struct device_attribute *attr, char *buf) |
1372 | { | 1371 | { |
1373 | struct w83795_data *data = dev_get_drvdata(dev); | 1372 | struct w83795_data *data = dev_get_drvdata(dev); |
1374 | int tmp; | 1373 | int tmp; |
1375 | 1374 | ||
1376 | if (data->enable_dts & 2) | 1375 | if (data->enable_dts & 2) |
1377 | tmp = 5; | 1376 | tmp = 5; |
1378 | else | 1377 | else |
1379 | tmp = 6; | 1378 | tmp = 6; |
1380 | 1379 | ||
1381 | return sprintf(buf, "%d\n", tmp); | 1380 | return sprintf(buf, "%d\n", tmp); |
1382 | } | 1381 | } |
1383 | 1382 | ||
1384 | static ssize_t | 1383 | static ssize_t |
1385 | show_dts(struct device *dev, struct device_attribute *attr, char *buf) | 1384 | show_dts(struct device *dev, struct device_attribute *attr, char *buf) |
1386 | { | 1385 | { |
1387 | struct sensor_device_attribute_2 *sensor_attr = | 1386 | struct sensor_device_attribute_2 *sensor_attr = |
1388 | to_sensor_dev_attr_2(attr); | 1387 | to_sensor_dev_attr_2(attr); |
1389 | int index = sensor_attr->index; | 1388 | int index = sensor_attr->index; |
1390 | struct w83795_data *data = w83795_update_device(dev); | 1389 | struct w83795_data *data = w83795_update_device(dev); |
1391 | long temp = temp_from_reg(data->dts[index]); | 1390 | long temp = temp_from_reg(data->dts[index]); |
1392 | 1391 | ||
1393 | temp += (data->dts_read_vrlsb[index] >> 6) * 250; | 1392 | temp += (data->dts_read_vrlsb[index] >> 6) * 250; |
1394 | return sprintf(buf, "%ld\n", temp); | 1393 | return sprintf(buf, "%ld\n", temp); |
1395 | } | 1394 | } |
1396 | 1395 | ||
1397 | static ssize_t | 1396 | static ssize_t |
1398 | show_dts_ext(struct device *dev, struct device_attribute *attr, char *buf) | 1397 | show_dts_ext(struct device *dev, struct device_attribute *attr, char *buf) |
1399 | { | 1398 | { |
1400 | struct sensor_device_attribute_2 *sensor_attr = | 1399 | struct sensor_device_attribute_2 *sensor_attr = |
1401 | to_sensor_dev_attr_2(attr); | 1400 | to_sensor_dev_attr_2(attr); |
1402 | int nr = sensor_attr->nr; | 1401 | int nr = sensor_attr->nr; |
1403 | struct w83795_data *data = dev_get_drvdata(dev); | 1402 | struct w83795_data *data = dev_get_drvdata(dev); |
1404 | long temp = temp_from_reg(data->dts_ext[nr]); | 1403 | long temp = temp_from_reg(data->dts_ext[nr]); |
1405 | 1404 | ||
1406 | return sprintf(buf, "%ld\n", temp); | 1405 | return sprintf(buf, "%ld\n", temp); |
1407 | } | 1406 | } |
1408 | 1407 | ||
1409 | static ssize_t | 1408 | static ssize_t |
1410 | store_dts_ext(struct device *dev, struct device_attribute *attr, | 1409 | store_dts_ext(struct device *dev, struct device_attribute *attr, |
1411 | const char *buf, size_t count) | 1410 | const char *buf, size_t count) |
1412 | { | 1411 | { |
1413 | struct sensor_device_attribute_2 *sensor_attr = | 1412 | struct sensor_device_attribute_2 *sensor_attr = |
1414 | to_sensor_dev_attr_2(attr); | 1413 | to_sensor_dev_attr_2(attr); |
1415 | int nr = sensor_attr->nr; | 1414 | int nr = sensor_attr->nr; |
1416 | struct i2c_client *client = to_i2c_client(dev); | 1415 | struct i2c_client *client = to_i2c_client(dev); |
1417 | struct w83795_data *data = i2c_get_clientdata(client); | 1416 | struct w83795_data *data = i2c_get_clientdata(client); |
1418 | long tmp; | 1417 | long tmp; |
1419 | 1418 | ||
1420 | if (kstrtol(buf, 10, &tmp) < 0) | 1419 | if (kstrtol(buf, 10, &tmp) < 0) |
1421 | return -EINVAL; | 1420 | return -EINVAL; |
1422 | 1421 | ||
1423 | mutex_lock(&data->update_lock); | 1422 | mutex_lock(&data->update_lock); |
1424 | data->dts_ext[nr] = temp_to_reg(tmp, -128, 127); | 1423 | data->dts_ext[nr] = temp_to_reg(tmp, -128, 127); |
1425 | w83795_write(client, W83795_REG_DTS_EXT(nr), data->dts_ext[nr]); | 1424 | w83795_write(client, W83795_REG_DTS_EXT(nr), data->dts_ext[nr]); |
1426 | mutex_unlock(&data->update_lock); | 1425 | mutex_unlock(&data->update_lock); |
1427 | return count; | 1426 | return count; |
1428 | } | 1427 | } |
1429 | 1428 | ||
1430 | 1429 | ||
1431 | static ssize_t | 1430 | static ssize_t |
1432 | show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) | 1431 | show_temp_mode(struct device *dev, struct device_attribute *attr, char *buf) |
1433 | { | 1432 | { |
1434 | struct w83795_data *data = dev_get_drvdata(dev); | 1433 | struct w83795_data *data = dev_get_drvdata(dev); |
1435 | struct sensor_device_attribute_2 *sensor_attr = | 1434 | struct sensor_device_attribute_2 *sensor_attr = |
1436 | to_sensor_dev_attr_2(attr); | 1435 | to_sensor_dev_attr_2(attr); |
1437 | int index = sensor_attr->index; | 1436 | int index = sensor_attr->index; |
1438 | int tmp; | 1437 | int tmp; |
1439 | 1438 | ||
1440 | if (data->temp_mode & (1 << index)) | 1439 | if (data->temp_mode & (1 << index)) |
1441 | tmp = 3; /* Thermal diode */ | 1440 | tmp = 3; /* Thermal diode */ |
1442 | else | 1441 | else |
1443 | tmp = 4; /* Thermistor */ | 1442 | tmp = 4; /* Thermistor */ |
1444 | 1443 | ||
1445 | return sprintf(buf, "%d\n", tmp); | 1444 | return sprintf(buf, "%d\n", tmp); |
1446 | } | 1445 | } |
1447 | 1446 | ||
1448 | /* Only for temp1-4 (temp5-6 can only be thermistor) */ | 1447 | /* Only for temp1-4 (temp5-6 can only be thermistor) */ |
1449 | static ssize_t | 1448 | static ssize_t |
1450 | store_temp_mode(struct device *dev, struct device_attribute *attr, | 1449 | store_temp_mode(struct device *dev, struct device_attribute *attr, |
1451 | const char *buf, size_t count) | 1450 | const char *buf, size_t count) |
1452 | { | 1451 | { |
1453 | struct i2c_client *client = to_i2c_client(dev); | 1452 | struct i2c_client *client = to_i2c_client(dev); |
1454 | struct w83795_data *data = i2c_get_clientdata(client); | 1453 | struct w83795_data *data = i2c_get_clientdata(client); |
1455 | struct sensor_device_attribute_2 *sensor_attr = | 1454 | struct sensor_device_attribute_2 *sensor_attr = |
1456 | to_sensor_dev_attr_2(attr); | 1455 | to_sensor_dev_attr_2(attr); |
1457 | int index = sensor_attr->index; | 1456 | int index = sensor_attr->index; |
1458 | int reg_shift; | 1457 | int reg_shift; |
1459 | unsigned long val; | 1458 | unsigned long val; |
1460 | u8 tmp; | 1459 | u8 tmp; |
1461 | 1460 | ||
1462 | if (kstrtoul(buf, 10, &val) < 0) | 1461 | if (kstrtoul(buf, 10, &val) < 0) |
1463 | return -EINVAL; | 1462 | return -EINVAL; |
1464 | if ((val != 4) && (val != 3)) | 1463 | if ((val != 4) && (val != 3)) |
1465 | return -EINVAL; | 1464 | return -EINVAL; |
1466 | 1465 | ||
1467 | mutex_lock(&data->update_lock); | 1466 | mutex_lock(&data->update_lock); |
1468 | if (val == 3) { | 1467 | if (val == 3) { |
1469 | /* Thermal diode */ | 1468 | /* Thermal diode */ |
1470 | val = 0x01; | 1469 | val = 0x01; |
1471 | data->temp_mode |= 1 << index; | 1470 | data->temp_mode |= 1 << index; |
1472 | } else if (val == 4) { | 1471 | } else if (val == 4) { |
1473 | /* Thermistor */ | 1472 | /* Thermistor */ |
1474 | val = 0x03; | 1473 | val = 0x03; |
1475 | data->temp_mode &= ~(1 << index); | 1474 | data->temp_mode &= ~(1 << index); |
1476 | } | 1475 | } |
1477 | 1476 | ||
1478 | reg_shift = 2 * index; | 1477 | reg_shift = 2 * index; |
1479 | tmp = w83795_read(client, W83795_REG_TEMP_CTRL2); | 1478 | tmp = w83795_read(client, W83795_REG_TEMP_CTRL2); |
1480 | tmp &= ~(0x03 << reg_shift); | 1479 | tmp &= ~(0x03 << reg_shift); |
1481 | tmp |= val << reg_shift; | 1480 | tmp |= val << reg_shift; |
1482 | w83795_write(client, W83795_REG_TEMP_CTRL2, tmp); | 1481 | w83795_write(client, W83795_REG_TEMP_CTRL2, tmp); |
1483 | 1482 | ||
1484 | mutex_unlock(&data->update_lock); | 1483 | mutex_unlock(&data->update_lock); |
1485 | return count; | 1484 | return count; |
1486 | } | 1485 | } |
1487 | 1486 | ||
1488 | 1487 | ||
1489 | /* show/store VIN */ | 1488 | /* show/store VIN */ |
1490 | static ssize_t | 1489 | static ssize_t |
1491 | show_in(struct device *dev, struct device_attribute *attr, char *buf) | 1490 | show_in(struct device *dev, struct device_attribute *attr, char *buf) |
1492 | { | 1491 | { |
1493 | struct sensor_device_attribute_2 *sensor_attr = | 1492 | struct sensor_device_attribute_2 *sensor_attr = |
1494 | to_sensor_dev_attr_2(attr); | 1493 | to_sensor_dev_attr_2(attr); |
1495 | int nr = sensor_attr->nr; | 1494 | int nr = sensor_attr->nr; |
1496 | int index = sensor_attr->index; | 1495 | int index = sensor_attr->index; |
1497 | struct w83795_data *data = w83795_update_device(dev); | 1496 | struct w83795_data *data = w83795_update_device(dev); |
1498 | u16 val = data->in[index][nr]; | 1497 | u16 val = data->in[index][nr]; |
1499 | u8 lsb_idx; | 1498 | u8 lsb_idx; |
1500 | 1499 | ||
1501 | switch (nr) { | 1500 | switch (nr) { |
1502 | case IN_READ: | 1501 | case IN_READ: |
1503 | /* calculate this value again by sensors as sensors3.conf */ | 1502 | /* calculate this value again by sensors as sensors3.conf */ |
1504 | if ((index >= 17) && | 1503 | if ((index >= 17) && |
1505 | !((data->has_gain >> (index - 17)) & 1)) | 1504 | !((data->has_gain >> (index - 17)) & 1)) |
1506 | val *= 8; | 1505 | val *= 8; |
1507 | break; | 1506 | break; |
1508 | case IN_MAX: | 1507 | case IN_MAX: |
1509 | case IN_LOW: | 1508 | case IN_LOW: |
1510 | lsb_idx = IN_LSB_SHIFT_IDX[index][IN_LSB_IDX]; | 1509 | lsb_idx = IN_LSB_SHIFT_IDX[index][IN_LSB_IDX]; |
1511 | val <<= 2; | 1510 | val <<= 2; |
1512 | val |= (data->in_lsb[lsb_idx][nr] >> | 1511 | val |= (data->in_lsb[lsb_idx][nr] >> |
1513 | IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]) & 0x03; | 1512 | IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]) & 0x03; |
1514 | if ((index >= 17) && | 1513 | if ((index >= 17) && |
1515 | !((data->has_gain >> (index - 17)) & 1)) | 1514 | !((data->has_gain >> (index - 17)) & 1)) |
1516 | val *= 8; | 1515 | val *= 8; |
1517 | break; | 1516 | break; |
1518 | } | 1517 | } |
1519 | val = in_from_reg(index, val); | 1518 | val = in_from_reg(index, val); |
1520 | 1519 | ||
1521 | return sprintf(buf, "%d\n", val); | 1520 | return sprintf(buf, "%d\n", val); |
1522 | } | 1521 | } |
1523 | 1522 | ||
1524 | static ssize_t | 1523 | static ssize_t |
1525 | store_in(struct device *dev, struct device_attribute *attr, | 1524 | store_in(struct device *dev, struct device_attribute *attr, |
1526 | const char *buf, size_t count) | 1525 | const char *buf, size_t count) |
1527 | { | 1526 | { |
1528 | struct sensor_device_attribute_2 *sensor_attr = | 1527 | struct sensor_device_attribute_2 *sensor_attr = |
1529 | to_sensor_dev_attr_2(attr); | 1528 | to_sensor_dev_attr_2(attr); |
1530 | int nr = sensor_attr->nr; | 1529 | int nr = sensor_attr->nr; |
1531 | int index = sensor_attr->index; | 1530 | int index = sensor_attr->index; |
1532 | struct i2c_client *client = to_i2c_client(dev); | 1531 | struct i2c_client *client = to_i2c_client(dev); |
1533 | struct w83795_data *data = i2c_get_clientdata(client); | 1532 | struct w83795_data *data = i2c_get_clientdata(client); |
1534 | unsigned long val; | 1533 | unsigned long val; |
1535 | u8 tmp; | 1534 | u8 tmp; |
1536 | u8 lsb_idx; | 1535 | u8 lsb_idx; |
1537 | 1536 | ||
1538 | if (kstrtoul(buf, 10, &val) < 0) | 1537 | if (kstrtoul(buf, 10, &val) < 0) |
1539 | return -EINVAL; | 1538 | return -EINVAL; |
1540 | val = in_to_reg(index, val); | 1539 | val = in_to_reg(index, val); |
1541 | 1540 | ||
1542 | if ((index >= 17) && | 1541 | if ((index >= 17) && |
1543 | !((data->has_gain >> (index - 17)) & 1)) | 1542 | !((data->has_gain >> (index - 17)) & 1)) |
1544 | val /= 8; | 1543 | val /= 8; |
1545 | val = SENSORS_LIMIT(val, 0, 0x3FF); | 1544 | val = SENSORS_LIMIT(val, 0, 0x3FF); |
1546 | mutex_lock(&data->update_lock); | 1545 | mutex_lock(&data->update_lock); |
1547 | 1546 | ||
1548 | lsb_idx = IN_LSB_SHIFT_IDX[index][IN_LSB_IDX]; | 1547 | lsb_idx = IN_LSB_SHIFT_IDX[index][IN_LSB_IDX]; |
1549 | tmp = w83795_read(client, IN_LSB_REG(lsb_idx, nr)); | 1548 | tmp = w83795_read(client, IN_LSB_REG(lsb_idx, nr)); |
1550 | tmp &= ~(0x03 << IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]); | 1549 | tmp &= ~(0x03 << IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]); |
1551 | tmp |= (val & 0x03) << IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]; | 1550 | tmp |= (val & 0x03) << IN_LSB_SHIFT_IDX[index][IN_LSB_SHIFT]; |
1552 | w83795_write(client, IN_LSB_REG(lsb_idx, nr), tmp); | 1551 | w83795_write(client, IN_LSB_REG(lsb_idx, nr), tmp); |
1553 | data->in_lsb[lsb_idx][nr] = tmp; | 1552 | data->in_lsb[lsb_idx][nr] = tmp; |
1554 | 1553 | ||
1555 | tmp = (val >> 2) & 0xff; | 1554 | tmp = (val >> 2) & 0xff; |
1556 | w83795_write(client, W83795_REG_IN[index][nr], tmp); | 1555 | w83795_write(client, W83795_REG_IN[index][nr], tmp); |
1557 | data->in[index][nr] = tmp; | 1556 | data->in[index][nr] = tmp; |
1558 | 1557 | ||
1559 | mutex_unlock(&data->update_lock); | 1558 | mutex_unlock(&data->update_lock); |
1560 | return count; | 1559 | return count; |
1561 | } | 1560 | } |
1562 | 1561 | ||
1563 | 1562 | ||
1564 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 1563 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
1565 | static ssize_t | 1564 | static ssize_t |
1566 | show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf) | 1565 | show_sf_setup(struct device *dev, struct device_attribute *attr, char *buf) |
1567 | { | 1566 | { |
1568 | struct sensor_device_attribute_2 *sensor_attr = | 1567 | struct sensor_device_attribute_2 *sensor_attr = |
1569 | to_sensor_dev_attr_2(attr); | 1568 | to_sensor_dev_attr_2(attr); |
1570 | int nr = sensor_attr->nr; | 1569 | int nr = sensor_attr->nr; |
1571 | struct w83795_data *data = w83795_update_pwm_config(dev); | 1570 | struct w83795_data *data = w83795_update_pwm_config(dev); |
1572 | u16 val = data->setup_pwm[nr]; | 1571 | u16 val = data->setup_pwm[nr]; |
1573 | 1572 | ||
1574 | switch (nr) { | 1573 | switch (nr) { |
1575 | case SETUP_PWM_UPTIME: | 1574 | case SETUP_PWM_UPTIME: |
1576 | case SETUP_PWM_DOWNTIME: | 1575 | case SETUP_PWM_DOWNTIME: |
1577 | val = time_from_reg(val); | 1576 | val = time_from_reg(val); |
1578 | break; | 1577 | break; |
1579 | } | 1578 | } |
1580 | 1579 | ||
1581 | return sprintf(buf, "%d\n", val); | 1580 | return sprintf(buf, "%d\n", val); |
1582 | } | 1581 | } |
1583 | 1582 | ||
1584 | static ssize_t | 1583 | static ssize_t |
1585 | store_sf_setup(struct device *dev, struct device_attribute *attr, | 1584 | store_sf_setup(struct device *dev, struct device_attribute *attr, |
1586 | const char *buf, size_t count) | 1585 | const char *buf, size_t count) |
1587 | { | 1586 | { |
1588 | struct sensor_device_attribute_2 *sensor_attr = | 1587 | struct sensor_device_attribute_2 *sensor_attr = |
1589 | to_sensor_dev_attr_2(attr); | 1588 | to_sensor_dev_attr_2(attr); |
1590 | int nr = sensor_attr->nr; | 1589 | int nr = sensor_attr->nr; |
1591 | struct i2c_client *client = to_i2c_client(dev); | 1590 | struct i2c_client *client = to_i2c_client(dev); |
1592 | struct w83795_data *data = i2c_get_clientdata(client); | 1591 | struct w83795_data *data = i2c_get_clientdata(client); |
1593 | unsigned long val; | 1592 | unsigned long val; |
1594 | 1593 | ||
1595 | if (kstrtoul(buf, 10, &val) < 0) | 1594 | if (kstrtoul(buf, 10, &val) < 0) |
1596 | return -EINVAL; | 1595 | return -EINVAL; |
1597 | 1596 | ||
1598 | switch (nr) { | 1597 | switch (nr) { |
1599 | case SETUP_PWM_DEFAULT: | 1598 | case SETUP_PWM_DEFAULT: |
1600 | val = SENSORS_LIMIT(val, 0, 0xff); | 1599 | val = SENSORS_LIMIT(val, 0, 0xff); |
1601 | break; | 1600 | break; |
1602 | case SETUP_PWM_UPTIME: | 1601 | case SETUP_PWM_UPTIME: |
1603 | case SETUP_PWM_DOWNTIME: | 1602 | case SETUP_PWM_DOWNTIME: |
1604 | val = time_to_reg(val); | 1603 | val = time_to_reg(val); |
1605 | if (val == 0) | 1604 | if (val == 0) |
1606 | return -EINVAL; | 1605 | return -EINVAL; |
1607 | break; | 1606 | break; |
1608 | } | 1607 | } |
1609 | 1608 | ||
1610 | mutex_lock(&data->update_lock); | 1609 | mutex_lock(&data->update_lock); |
1611 | data->setup_pwm[nr] = val; | 1610 | data->setup_pwm[nr] = val; |
1612 | w83795_write(client, W83795_REG_SETUP_PWM(nr), val); | 1611 | w83795_write(client, W83795_REG_SETUP_PWM(nr), val); |
1613 | mutex_unlock(&data->update_lock); | 1612 | mutex_unlock(&data->update_lock); |
1614 | return count; | 1613 | return count; |
1615 | } | 1614 | } |
1616 | #endif | 1615 | #endif |
1617 | 1616 | ||
1618 | 1617 | ||
1619 | #define NOT_USED -1 | 1618 | #define NOT_USED -1 |
1620 | 1619 | ||
1621 | /* | 1620 | /* |
1622 | * Don't change the attribute order, _max, _min and _beep are accessed by index | 1621 | * Don't change the attribute order, _max, _min and _beep are accessed by index |
1623 | * somewhere else in the code | 1622 | * somewhere else in the code |
1624 | */ | 1623 | */ |
1625 | #define SENSOR_ATTR_IN(index) { \ | 1624 | #define SENSOR_ATTR_IN(index) { \ |
1626 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ | 1625 | SENSOR_ATTR_2(in##index##_input, S_IRUGO, show_in, NULL, \ |
1627 | IN_READ, index), \ | 1626 | IN_READ, index), \ |
1628 | SENSOR_ATTR_2(in##index##_max, S_IRUGO | S_IWUSR, show_in, \ | 1627 | SENSOR_ATTR_2(in##index##_max, S_IRUGO | S_IWUSR, show_in, \ |
1629 | store_in, IN_MAX, index), \ | 1628 | store_in, IN_MAX, index), \ |
1630 | SENSOR_ATTR_2(in##index##_min, S_IRUGO | S_IWUSR, show_in, \ | 1629 | SENSOR_ATTR_2(in##index##_min, S_IRUGO | S_IWUSR, show_in, \ |
1631 | store_in, IN_LOW, index), \ | 1630 | store_in, IN_LOW, index), \ |
1632 | SENSOR_ATTR_2(in##index##_alarm, S_IRUGO, show_alarm_beep, \ | 1631 | SENSOR_ATTR_2(in##index##_alarm, S_IRUGO, show_alarm_beep, \ |
1633 | NULL, ALARM_STATUS, index + ((index > 14) ? 1 : 0)), \ | 1632 | NULL, ALARM_STATUS, index + ((index > 14) ? 1 : 0)), \ |
1634 | SENSOR_ATTR_2(in##index##_beep, S_IWUSR | S_IRUGO, \ | 1633 | SENSOR_ATTR_2(in##index##_beep, S_IWUSR | S_IRUGO, \ |
1635 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1634 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
1636 | index + ((index > 14) ? 1 : 0)) } | 1635 | index + ((index > 14) ? 1 : 0)) } |
1637 | 1636 | ||
1638 | /* | 1637 | /* |
1639 | * Don't change the attribute order, _beep is accessed by index | 1638 | * Don't change the attribute order, _beep is accessed by index |
1640 | * somewhere else in the code | 1639 | * somewhere else in the code |
1641 | */ | 1640 | */ |
1642 | #define SENSOR_ATTR_FAN(index) { \ | 1641 | #define SENSOR_ATTR_FAN(index) { \ |
1643 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ | 1642 | SENSOR_ATTR_2(fan##index##_input, S_IRUGO, show_fan, \ |
1644 | NULL, FAN_INPUT, index - 1), \ | 1643 | NULL, FAN_INPUT, index - 1), \ |
1645 | SENSOR_ATTR_2(fan##index##_min, S_IWUSR | S_IRUGO, \ | 1644 | SENSOR_ATTR_2(fan##index##_min, S_IWUSR | S_IRUGO, \ |
1646 | show_fan, store_fan_min, FAN_MIN, index - 1), \ | 1645 | show_fan, store_fan_min, FAN_MIN, index - 1), \ |
1647 | SENSOR_ATTR_2(fan##index##_alarm, S_IRUGO, show_alarm_beep, \ | 1646 | SENSOR_ATTR_2(fan##index##_alarm, S_IRUGO, show_alarm_beep, \ |
1648 | NULL, ALARM_STATUS, index + 31), \ | 1647 | NULL, ALARM_STATUS, index + 31), \ |
1649 | SENSOR_ATTR_2(fan##index##_beep, S_IWUSR | S_IRUGO, \ | 1648 | SENSOR_ATTR_2(fan##index##_beep, S_IWUSR | S_IRUGO, \ |
1650 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 31) } | 1649 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 31) } |
1651 | 1650 | ||
1652 | #define SENSOR_ATTR_PWM(index) { \ | 1651 | #define SENSOR_ATTR_PWM(index) { \ |
1653 | SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm, \ | 1652 | SENSOR_ATTR_2(pwm##index, S_IWUSR | S_IRUGO, show_pwm, \ |
1654 | store_pwm, PWM_OUTPUT, index - 1), \ | 1653 | store_pwm, PWM_OUTPUT, index - 1), \ |
1655 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ | 1654 | SENSOR_ATTR_2(pwm##index##_enable, S_IWUSR | S_IRUGO, \ |
1656 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ | 1655 | show_pwm_enable, store_pwm_enable, NOT_USED, index - 1), \ |
1657 | SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ | 1656 | SENSOR_ATTR_2(pwm##index##_mode, S_IRUGO, \ |
1658 | show_pwm_mode, NULL, NOT_USED, index - 1), \ | 1657 | show_pwm_mode, NULL, NOT_USED, index - 1), \ |
1659 | SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO, \ | 1658 | SENSOR_ATTR_2(pwm##index##_freq, S_IWUSR | S_IRUGO, \ |
1660 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ | 1659 | show_pwm, store_pwm, PWM_FREQ, index - 1), \ |
1661 | SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO, \ | 1660 | SENSOR_ATTR_2(pwm##index##_nonstop, S_IWUSR | S_IRUGO, \ |
1662 | show_pwm, store_pwm, PWM_NONSTOP, index - 1), \ | 1661 | show_pwm, store_pwm, PWM_NONSTOP, index - 1), \ |
1663 | SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO, \ | 1662 | SENSOR_ATTR_2(pwm##index##_start, S_IWUSR | S_IRUGO, \ |
1664 | show_pwm, store_pwm, PWM_START, index - 1), \ | 1663 | show_pwm, store_pwm, PWM_START, index - 1), \ |
1665 | SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO, \ | 1664 | SENSOR_ATTR_2(pwm##index##_stop_time, S_IWUSR | S_IRUGO, \ |
1666 | show_pwm, store_pwm, PWM_STOP_TIME, index - 1), \ | 1665 | show_pwm, store_pwm, PWM_STOP_TIME, index - 1), \ |
1667 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ | 1666 | SENSOR_ATTR_2(fan##index##_target, S_IWUSR | S_IRUGO, \ |
1668 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } | 1667 | show_fanin, store_fanin, FANIN_TARGET, index - 1) } |
1669 | 1668 | ||
1670 | /* | 1669 | /* |
1671 | * Don't change the attribute order, _beep is accessed by index | 1670 | * Don't change the attribute order, _beep is accessed by index |
1672 | * somewhere else in the code | 1671 | * somewhere else in the code |
1673 | */ | 1672 | */ |
1674 | #define SENSOR_ATTR_DTS(index) { \ | 1673 | #define SENSOR_ATTR_DTS(index) { \ |
1675 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ | 1674 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO , \ |
1676 | show_dts_mode, NULL, NOT_USED, index - 7), \ | 1675 | show_dts_mode, NULL, NOT_USED, index - 7), \ |
1677 | SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_dts, \ | 1676 | SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_dts, \ |
1678 | NULL, NOT_USED, index - 7), \ | 1677 | NULL, NOT_USED, index - 7), \ |
1679 | SENSOR_ATTR_2(temp##index##_crit, S_IRUGO | S_IWUSR, show_dts_ext, \ | 1678 | SENSOR_ATTR_2(temp##index##_crit, S_IRUGO | S_IWUSR, show_dts_ext, \ |
1680 | store_dts_ext, DTS_CRIT, NOT_USED), \ | 1679 | store_dts_ext, DTS_CRIT, NOT_USED), \ |
1681 | SENSOR_ATTR_2(temp##index##_crit_hyst, S_IRUGO | S_IWUSR, \ | 1680 | SENSOR_ATTR_2(temp##index##_crit_hyst, S_IRUGO | S_IWUSR, \ |
1682 | show_dts_ext, store_dts_ext, DTS_CRIT_HYST, NOT_USED), \ | 1681 | show_dts_ext, store_dts_ext, DTS_CRIT_HYST, NOT_USED), \ |
1683 | SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_dts_ext, \ | 1682 | SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_dts_ext, \ |
1684 | store_dts_ext, DTS_WARN, NOT_USED), \ | 1683 | store_dts_ext, DTS_WARN, NOT_USED), \ |
1685 | SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR, \ | 1684 | SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR, \ |
1686 | show_dts_ext, store_dts_ext, DTS_WARN_HYST, NOT_USED), \ | 1685 | show_dts_ext, store_dts_ext, DTS_WARN_HYST, NOT_USED), \ |
1687 | SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO, \ | 1686 | SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO, \ |
1688 | show_alarm_beep, NULL, ALARM_STATUS, index + 17), \ | 1687 | show_alarm_beep, NULL, ALARM_STATUS, index + 17), \ |
1689 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1688 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
1690 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } | 1689 | show_alarm_beep, store_beep, BEEP_ENABLE, index + 17) } |
1691 | 1690 | ||
1692 | /* | 1691 | /* |
1693 | * Don't change the attribute order, _beep is accessed by index | 1692 | * Don't change the attribute order, _beep is accessed by index |
1694 | * somewhere else in the code | 1693 | * somewhere else in the code |
1695 | */ | 1694 | */ |
1696 | #define SENSOR_ATTR_TEMP(index) { \ | 1695 | #define SENSOR_ATTR_TEMP(index) { \ |
1697 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ | 1696 | SENSOR_ATTR_2(temp##index##_type, S_IRUGO | (index < 4 ? S_IWUSR : 0), \ |
1698 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ | 1697 | show_temp_mode, store_temp_mode, NOT_USED, index - 1), \ |
1699 | SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp, \ | 1698 | SENSOR_ATTR_2(temp##index##_input, S_IRUGO, show_temp, \ |
1700 | NULL, TEMP_READ, index - 1), \ | 1699 | NULL, TEMP_READ, index - 1), \ |
1701 | SENSOR_ATTR_2(temp##index##_crit, S_IRUGO | S_IWUSR, show_temp, \ | 1700 | SENSOR_ATTR_2(temp##index##_crit, S_IRUGO | S_IWUSR, show_temp, \ |
1702 | store_temp, TEMP_CRIT, index - 1), \ | 1701 | store_temp, TEMP_CRIT, index - 1), \ |
1703 | SENSOR_ATTR_2(temp##index##_crit_hyst, S_IRUGO | S_IWUSR, \ | 1702 | SENSOR_ATTR_2(temp##index##_crit_hyst, S_IRUGO | S_IWUSR, \ |
1704 | show_temp, store_temp, TEMP_CRIT_HYST, index - 1), \ | 1703 | show_temp, store_temp, TEMP_CRIT_HYST, index - 1), \ |
1705 | SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_temp, \ | 1704 | SENSOR_ATTR_2(temp##index##_max, S_IRUGO | S_IWUSR, show_temp, \ |
1706 | store_temp, TEMP_WARN, index - 1), \ | 1705 | store_temp, TEMP_WARN, index - 1), \ |
1707 | SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR, \ | 1706 | SENSOR_ATTR_2(temp##index##_max_hyst, S_IRUGO | S_IWUSR, \ |
1708 | show_temp, store_temp, TEMP_WARN_HYST, index - 1), \ | 1707 | show_temp, store_temp, TEMP_WARN_HYST, index - 1), \ |
1709 | SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO, \ | 1708 | SENSOR_ATTR_2(temp##index##_alarm, S_IRUGO, \ |
1710 | show_alarm_beep, NULL, ALARM_STATUS, \ | 1709 | show_alarm_beep, NULL, ALARM_STATUS, \ |
1711 | index + (index > 4 ? 11 : 17)), \ | 1710 | index + (index > 4 ? 11 : 17)), \ |
1712 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ | 1711 | SENSOR_ATTR_2(temp##index##_beep, S_IWUSR | S_IRUGO, \ |
1713 | show_alarm_beep, store_beep, BEEP_ENABLE, \ | 1712 | show_alarm_beep, store_beep, BEEP_ENABLE, \ |
1714 | index + (index > 4 ? 11 : 17)), \ | 1713 | index + (index > 4 ? 11 : 17)), \ |
1715 | SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ | 1714 | SENSOR_ATTR_2(temp##index##_pwm_enable, S_IWUSR | S_IRUGO, \ |
1716 | show_temp_pwm_enable, store_temp_pwm_enable, \ | 1715 | show_temp_pwm_enable, store_temp_pwm_enable, \ |
1717 | TEMP_PWM_ENABLE, index - 1), \ | 1716 | TEMP_PWM_ENABLE, index - 1), \ |
1718 | SENSOR_ATTR_2(temp##index##_auto_channels_pwm, S_IWUSR | S_IRUGO, \ | 1717 | SENSOR_ATTR_2(temp##index##_auto_channels_pwm, S_IWUSR | S_IRUGO, \ |
1719 | show_temp_pwm_enable, store_temp_pwm_enable, \ | 1718 | show_temp_pwm_enable, store_temp_pwm_enable, \ |
1720 | TEMP_PWM_FAN_MAP, index - 1), \ | 1719 | TEMP_PWM_FAN_MAP, index - 1), \ |
1721 | SENSOR_ATTR_2(thermal_cruise##index, S_IWUSR | S_IRUGO, \ | 1720 | SENSOR_ATTR_2(thermal_cruise##index, S_IWUSR | S_IRUGO, \ |
1722 | show_temp_pwm, store_temp_pwm, TEMP_PWM_TTTI, index - 1), \ | 1721 | show_temp_pwm, store_temp_pwm, TEMP_PWM_TTTI, index - 1), \ |
1723 | SENSOR_ATTR_2(temp##index##_warn, S_IWUSR | S_IRUGO, \ | 1722 | SENSOR_ATTR_2(temp##index##_warn, S_IWUSR | S_IRUGO, \ |
1724 | show_temp_pwm, store_temp_pwm, TEMP_PWM_CTFS, index - 1), \ | 1723 | show_temp_pwm, store_temp_pwm, TEMP_PWM_CTFS, index - 1), \ |
1725 | SENSOR_ATTR_2(temp##index##_warn_hyst, S_IWUSR | S_IRUGO, \ | 1724 | SENSOR_ATTR_2(temp##index##_warn_hyst, S_IWUSR | S_IRUGO, \ |
1726 | show_temp_pwm, store_temp_pwm, TEMP_PWM_HCT, index - 1), \ | 1725 | show_temp_pwm, store_temp_pwm, TEMP_PWM_HCT, index - 1), \ |
1727 | SENSOR_ATTR_2(temp##index##_operation_hyst, S_IWUSR | S_IRUGO, \ | 1726 | SENSOR_ATTR_2(temp##index##_operation_hyst, S_IWUSR | S_IRUGO, \ |
1728 | show_temp_pwm, store_temp_pwm, TEMP_PWM_HOT, index - 1), \ | 1727 | show_temp_pwm, store_temp_pwm, TEMP_PWM_HOT, index - 1), \ |
1729 | SENSOR_ATTR_2(temp##index##_auto_point1_pwm, S_IRUGO | S_IWUSR, \ | 1728 | SENSOR_ATTR_2(temp##index##_auto_point1_pwm, S_IRUGO | S_IWUSR, \ |
1730 | show_sf4_pwm, store_sf4_pwm, 0, index - 1), \ | 1729 | show_sf4_pwm, store_sf4_pwm, 0, index - 1), \ |
1731 | SENSOR_ATTR_2(temp##index##_auto_point2_pwm, S_IRUGO | S_IWUSR, \ | 1730 | SENSOR_ATTR_2(temp##index##_auto_point2_pwm, S_IRUGO | S_IWUSR, \ |
1732 | show_sf4_pwm, store_sf4_pwm, 1, index - 1), \ | 1731 | show_sf4_pwm, store_sf4_pwm, 1, index - 1), \ |
1733 | SENSOR_ATTR_2(temp##index##_auto_point3_pwm, S_IRUGO | S_IWUSR, \ | 1732 | SENSOR_ATTR_2(temp##index##_auto_point3_pwm, S_IRUGO | S_IWUSR, \ |
1734 | show_sf4_pwm, store_sf4_pwm, 2, index - 1), \ | 1733 | show_sf4_pwm, store_sf4_pwm, 2, index - 1), \ |
1735 | SENSOR_ATTR_2(temp##index##_auto_point4_pwm, S_IRUGO | S_IWUSR, \ | 1734 | SENSOR_ATTR_2(temp##index##_auto_point4_pwm, S_IRUGO | S_IWUSR, \ |
1736 | show_sf4_pwm, store_sf4_pwm, 3, index - 1), \ | 1735 | show_sf4_pwm, store_sf4_pwm, 3, index - 1), \ |
1737 | SENSOR_ATTR_2(temp##index##_auto_point5_pwm, S_IRUGO | S_IWUSR, \ | 1736 | SENSOR_ATTR_2(temp##index##_auto_point5_pwm, S_IRUGO | S_IWUSR, \ |
1738 | show_sf4_pwm, store_sf4_pwm, 4, index - 1), \ | 1737 | show_sf4_pwm, store_sf4_pwm, 4, index - 1), \ |
1739 | SENSOR_ATTR_2(temp##index##_auto_point6_pwm, S_IRUGO | S_IWUSR, \ | 1738 | SENSOR_ATTR_2(temp##index##_auto_point6_pwm, S_IRUGO | S_IWUSR, \ |
1740 | show_sf4_pwm, store_sf4_pwm, 5, index - 1), \ | 1739 | show_sf4_pwm, store_sf4_pwm, 5, index - 1), \ |
1741 | SENSOR_ATTR_2(temp##index##_auto_point7_pwm, S_IRUGO | S_IWUSR, \ | 1740 | SENSOR_ATTR_2(temp##index##_auto_point7_pwm, S_IRUGO | S_IWUSR, \ |
1742 | show_sf4_pwm, store_sf4_pwm, 6, index - 1), \ | 1741 | show_sf4_pwm, store_sf4_pwm, 6, index - 1), \ |
1743 | SENSOR_ATTR_2(temp##index##_auto_point1_temp, S_IRUGO | S_IWUSR,\ | 1742 | SENSOR_ATTR_2(temp##index##_auto_point1_temp, S_IRUGO | S_IWUSR,\ |
1744 | show_sf4_temp, store_sf4_temp, 0, index - 1), \ | 1743 | show_sf4_temp, store_sf4_temp, 0, index - 1), \ |
1745 | SENSOR_ATTR_2(temp##index##_auto_point2_temp, S_IRUGO | S_IWUSR,\ | 1744 | SENSOR_ATTR_2(temp##index##_auto_point2_temp, S_IRUGO | S_IWUSR,\ |
1746 | show_sf4_temp, store_sf4_temp, 1, index - 1), \ | 1745 | show_sf4_temp, store_sf4_temp, 1, index - 1), \ |
1747 | SENSOR_ATTR_2(temp##index##_auto_point3_temp, S_IRUGO | S_IWUSR,\ | 1746 | SENSOR_ATTR_2(temp##index##_auto_point3_temp, S_IRUGO | S_IWUSR,\ |
1748 | show_sf4_temp, store_sf4_temp, 2, index - 1), \ | 1747 | show_sf4_temp, store_sf4_temp, 2, index - 1), \ |
1749 | SENSOR_ATTR_2(temp##index##_auto_point4_temp, S_IRUGO | S_IWUSR,\ | 1748 | SENSOR_ATTR_2(temp##index##_auto_point4_temp, S_IRUGO | S_IWUSR,\ |
1750 | show_sf4_temp, store_sf4_temp, 3, index - 1), \ | 1749 | show_sf4_temp, store_sf4_temp, 3, index - 1), \ |
1751 | SENSOR_ATTR_2(temp##index##_auto_point5_temp, S_IRUGO | S_IWUSR,\ | 1750 | SENSOR_ATTR_2(temp##index##_auto_point5_temp, S_IRUGO | S_IWUSR,\ |
1752 | show_sf4_temp, store_sf4_temp, 4, index - 1), \ | 1751 | show_sf4_temp, store_sf4_temp, 4, index - 1), \ |
1753 | SENSOR_ATTR_2(temp##index##_auto_point6_temp, S_IRUGO | S_IWUSR,\ | 1752 | SENSOR_ATTR_2(temp##index##_auto_point6_temp, S_IRUGO | S_IWUSR,\ |
1754 | show_sf4_temp, store_sf4_temp, 5, index - 1), \ | 1753 | show_sf4_temp, store_sf4_temp, 5, index - 1), \ |
1755 | SENSOR_ATTR_2(temp##index##_auto_point7_temp, S_IRUGO | S_IWUSR,\ | 1754 | SENSOR_ATTR_2(temp##index##_auto_point7_temp, S_IRUGO | S_IWUSR,\ |
1756 | show_sf4_temp, store_sf4_temp, 6, index - 1) } | 1755 | show_sf4_temp, store_sf4_temp, 6, index - 1) } |
1757 | 1756 | ||
1758 | 1757 | ||
1759 | static struct sensor_device_attribute_2 w83795_in[][5] = { | 1758 | static struct sensor_device_attribute_2 w83795_in[][5] = { |
1760 | SENSOR_ATTR_IN(0), | 1759 | SENSOR_ATTR_IN(0), |
1761 | SENSOR_ATTR_IN(1), | 1760 | SENSOR_ATTR_IN(1), |
1762 | SENSOR_ATTR_IN(2), | 1761 | SENSOR_ATTR_IN(2), |
1763 | SENSOR_ATTR_IN(3), | 1762 | SENSOR_ATTR_IN(3), |
1764 | SENSOR_ATTR_IN(4), | 1763 | SENSOR_ATTR_IN(4), |
1765 | SENSOR_ATTR_IN(5), | 1764 | SENSOR_ATTR_IN(5), |
1766 | SENSOR_ATTR_IN(6), | 1765 | SENSOR_ATTR_IN(6), |
1767 | SENSOR_ATTR_IN(7), | 1766 | SENSOR_ATTR_IN(7), |
1768 | SENSOR_ATTR_IN(8), | 1767 | SENSOR_ATTR_IN(8), |
1769 | SENSOR_ATTR_IN(9), | 1768 | SENSOR_ATTR_IN(9), |
1770 | SENSOR_ATTR_IN(10), | 1769 | SENSOR_ATTR_IN(10), |
1771 | SENSOR_ATTR_IN(11), | 1770 | SENSOR_ATTR_IN(11), |
1772 | SENSOR_ATTR_IN(12), | 1771 | SENSOR_ATTR_IN(12), |
1773 | SENSOR_ATTR_IN(13), | 1772 | SENSOR_ATTR_IN(13), |
1774 | SENSOR_ATTR_IN(14), | 1773 | SENSOR_ATTR_IN(14), |
1775 | SENSOR_ATTR_IN(15), | 1774 | SENSOR_ATTR_IN(15), |
1776 | SENSOR_ATTR_IN(16), | 1775 | SENSOR_ATTR_IN(16), |
1777 | SENSOR_ATTR_IN(17), | 1776 | SENSOR_ATTR_IN(17), |
1778 | SENSOR_ATTR_IN(18), | 1777 | SENSOR_ATTR_IN(18), |
1779 | SENSOR_ATTR_IN(19), | 1778 | SENSOR_ATTR_IN(19), |
1780 | SENSOR_ATTR_IN(20), | 1779 | SENSOR_ATTR_IN(20), |
1781 | }; | 1780 | }; |
1782 | 1781 | ||
1783 | static const struct sensor_device_attribute_2 w83795_fan[][4] = { | 1782 | static const struct sensor_device_attribute_2 w83795_fan[][4] = { |
1784 | SENSOR_ATTR_FAN(1), | 1783 | SENSOR_ATTR_FAN(1), |
1785 | SENSOR_ATTR_FAN(2), | 1784 | SENSOR_ATTR_FAN(2), |
1786 | SENSOR_ATTR_FAN(3), | 1785 | SENSOR_ATTR_FAN(3), |
1787 | SENSOR_ATTR_FAN(4), | 1786 | SENSOR_ATTR_FAN(4), |
1788 | SENSOR_ATTR_FAN(5), | 1787 | SENSOR_ATTR_FAN(5), |
1789 | SENSOR_ATTR_FAN(6), | 1788 | SENSOR_ATTR_FAN(6), |
1790 | SENSOR_ATTR_FAN(7), | 1789 | SENSOR_ATTR_FAN(7), |
1791 | SENSOR_ATTR_FAN(8), | 1790 | SENSOR_ATTR_FAN(8), |
1792 | SENSOR_ATTR_FAN(9), | 1791 | SENSOR_ATTR_FAN(9), |
1793 | SENSOR_ATTR_FAN(10), | 1792 | SENSOR_ATTR_FAN(10), |
1794 | SENSOR_ATTR_FAN(11), | 1793 | SENSOR_ATTR_FAN(11), |
1795 | SENSOR_ATTR_FAN(12), | 1794 | SENSOR_ATTR_FAN(12), |
1796 | SENSOR_ATTR_FAN(13), | 1795 | SENSOR_ATTR_FAN(13), |
1797 | SENSOR_ATTR_FAN(14), | 1796 | SENSOR_ATTR_FAN(14), |
1798 | }; | 1797 | }; |
1799 | 1798 | ||
1800 | static const struct sensor_device_attribute_2 w83795_temp[][28] = { | 1799 | static const struct sensor_device_attribute_2 w83795_temp[][28] = { |
1801 | SENSOR_ATTR_TEMP(1), | 1800 | SENSOR_ATTR_TEMP(1), |
1802 | SENSOR_ATTR_TEMP(2), | 1801 | SENSOR_ATTR_TEMP(2), |
1803 | SENSOR_ATTR_TEMP(3), | 1802 | SENSOR_ATTR_TEMP(3), |
1804 | SENSOR_ATTR_TEMP(4), | 1803 | SENSOR_ATTR_TEMP(4), |
1805 | SENSOR_ATTR_TEMP(5), | 1804 | SENSOR_ATTR_TEMP(5), |
1806 | SENSOR_ATTR_TEMP(6), | 1805 | SENSOR_ATTR_TEMP(6), |
1807 | }; | 1806 | }; |
1808 | 1807 | ||
1809 | static const struct sensor_device_attribute_2 w83795_dts[][8] = { | 1808 | static const struct sensor_device_attribute_2 w83795_dts[][8] = { |
1810 | SENSOR_ATTR_DTS(7), | 1809 | SENSOR_ATTR_DTS(7), |
1811 | SENSOR_ATTR_DTS(8), | 1810 | SENSOR_ATTR_DTS(8), |
1812 | SENSOR_ATTR_DTS(9), | 1811 | SENSOR_ATTR_DTS(9), |
1813 | SENSOR_ATTR_DTS(10), | 1812 | SENSOR_ATTR_DTS(10), |
1814 | SENSOR_ATTR_DTS(11), | 1813 | SENSOR_ATTR_DTS(11), |
1815 | SENSOR_ATTR_DTS(12), | 1814 | SENSOR_ATTR_DTS(12), |
1816 | SENSOR_ATTR_DTS(13), | 1815 | SENSOR_ATTR_DTS(13), |
1817 | SENSOR_ATTR_DTS(14), | 1816 | SENSOR_ATTR_DTS(14), |
1818 | }; | 1817 | }; |
1819 | 1818 | ||
1820 | static const struct sensor_device_attribute_2 w83795_pwm[][8] = { | 1819 | static const struct sensor_device_attribute_2 w83795_pwm[][8] = { |
1821 | SENSOR_ATTR_PWM(1), | 1820 | SENSOR_ATTR_PWM(1), |
1822 | SENSOR_ATTR_PWM(2), | 1821 | SENSOR_ATTR_PWM(2), |
1823 | SENSOR_ATTR_PWM(3), | 1822 | SENSOR_ATTR_PWM(3), |
1824 | SENSOR_ATTR_PWM(4), | 1823 | SENSOR_ATTR_PWM(4), |
1825 | SENSOR_ATTR_PWM(5), | 1824 | SENSOR_ATTR_PWM(5), |
1826 | SENSOR_ATTR_PWM(6), | 1825 | SENSOR_ATTR_PWM(6), |
1827 | SENSOR_ATTR_PWM(7), | 1826 | SENSOR_ATTR_PWM(7), |
1828 | SENSOR_ATTR_PWM(8), | 1827 | SENSOR_ATTR_PWM(8), |
1829 | }; | 1828 | }; |
1830 | 1829 | ||
1831 | static const struct sensor_device_attribute_2 w83795_tss[6] = { | 1830 | static const struct sensor_device_attribute_2 w83795_tss[6] = { |
1832 | SENSOR_ATTR_2(temp1_source_sel, S_IWUSR | S_IRUGO, | 1831 | SENSOR_ATTR_2(temp1_source_sel, S_IWUSR | S_IRUGO, |
1833 | show_temp_src, store_temp_src, NOT_USED, 0), | 1832 | show_temp_src, store_temp_src, NOT_USED, 0), |
1834 | SENSOR_ATTR_2(temp2_source_sel, S_IWUSR | S_IRUGO, | 1833 | SENSOR_ATTR_2(temp2_source_sel, S_IWUSR | S_IRUGO, |
1835 | show_temp_src, store_temp_src, NOT_USED, 1), | 1834 | show_temp_src, store_temp_src, NOT_USED, 1), |
1836 | SENSOR_ATTR_2(temp3_source_sel, S_IWUSR | S_IRUGO, | 1835 | SENSOR_ATTR_2(temp3_source_sel, S_IWUSR | S_IRUGO, |
1837 | show_temp_src, store_temp_src, NOT_USED, 2), | 1836 | show_temp_src, store_temp_src, NOT_USED, 2), |
1838 | SENSOR_ATTR_2(temp4_source_sel, S_IWUSR | S_IRUGO, | 1837 | SENSOR_ATTR_2(temp4_source_sel, S_IWUSR | S_IRUGO, |
1839 | show_temp_src, store_temp_src, NOT_USED, 3), | 1838 | show_temp_src, store_temp_src, NOT_USED, 3), |
1840 | SENSOR_ATTR_2(temp5_source_sel, S_IWUSR | S_IRUGO, | 1839 | SENSOR_ATTR_2(temp5_source_sel, S_IWUSR | S_IRUGO, |
1841 | show_temp_src, store_temp_src, NOT_USED, 4), | 1840 | show_temp_src, store_temp_src, NOT_USED, 4), |
1842 | SENSOR_ATTR_2(temp6_source_sel, S_IWUSR | S_IRUGO, | 1841 | SENSOR_ATTR_2(temp6_source_sel, S_IWUSR | S_IRUGO, |
1843 | show_temp_src, store_temp_src, NOT_USED, 5), | 1842 | show_temp_src, store_temp_src, NOT_USED, 5), |
1844 | }; | 1843 | }; |
1845 | 1844 | ||
1846 | static const struct sensor_device_attribute_2 sda_single_files[] = { | 1845 | static const struct sensor_device_attribute_2 sda_single_files[] = { |
1847 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, | 1846 | SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep, |
1848 | store_chassis_clear, ALARM_STATUS, 46), | 1847 | store_chassis_clear, ALARM_STATUS, 46), |
1849 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 1848 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
1850 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, | 1849 | SENSOR_ATTR_2(speed_cruise_tolerance, S_IWUSR | S_IRUGO, show_fanin, |
1851 | store_fanin, FANIN_TOL, NOT_USED), | 1850 | store_fanin, FANIN_TOL, NOT_USED), |
1852 | SENSOR_ATTR_2(pwm_default, S_IWUSR | S_IRUGO, show_sf_setup, | 1851 | SENSOR_ATTR_2(pwm_default, S_IWUSR | S_IRUGO, show_sf_setup, |
1853 | store_sf_setup, SETUP_PWM_DEFAULT, NOT_USED), | 1852 | store_sf_setup, SETUP_PWM_DEFAULT, NOT_USED), |
1854 | SENSOR_ATTR_2(pwm_uptime, S_IWUSR | S_IRUGO, show_sf_setup, | 1853 | SENSOR_ATTR_2(pwm_uptime, S_IWUSR | S_IRUGO, show_sf_setup, |
1855 | store_sf_setup, SETUP_PWM_UPTIME, NOT_USED), | 1854 | store_sf_setup, SETUP_PWM_UPTIME, NOT_USED), |
1856 | SENSOR_ATTR_2(pwm_downtime, S_IWUSR | S_IRUGO, show_sf_setup, | 1855 | SENSOR_ATTR_2(pwm_downtime, S_IWUSR | S_IRUGO, show_sf_setup, |
1857 | store_sf_setup, SETUP_PWM_DOWNTIME, NOT_USED), | 1856 | store_sf_setup, SETUP_PWM_DOWNTIME, NOT_USED), |
1858 | #endif | 1857 | #endif |
1859 | }; | 1858 | }; |
1860 | 1859 | ||
1861 | static const struct sensor_device_attribute_2 sda_beep_files[] = { | 1860 | static const struct sensor_device_attribute_2 sda_beep_files[] = { |
1862 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, | 1861 | SENSOR_ATTR_2(intrusion0_beep, S_IWUSR | S_IRUGO, show_alarm_beep, |
1863 | store_beep, BEEP_ENABLE, 46), | 1862 | store_beep, BEEP_ENABLE, 46), |
1864 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, | 1863 | SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_alarm_beep, |
1865 | store_beep, BEEP_ENABLE, 47), | 1864 | store_beep, BEEP_ENABLE, 47), |
1866 | }; | 1865 | }; |
1867 | 1866 | ||
1868 | /* | 1867 | /* |
1869 | * Driver interface | 1868 | * Driver interface |
1870 | */ | 1869 | */ |
1871 | 1870 | ||
1872 | static void w83795_init_client(struct i2c_client *client) | 1871 | static void w83795_init_client(struct i2c_client *client) |
1873 | { | 1872 | { |
1874 | struct w83795_data *data = i2c_get_clientdata(client); | 1873 | struct w83795_data *data = i2c_get_clientdata(client); |
1875 | static const u16 clkin[4] = { /* in kHz */ | 1874 | static const u16 clkin[4] = { /* in kHz */ |
1876 | 14318, 24000, 33333, 48000 | 1875 | 14318, 24000, 33333, 48000 |
1877 | }; | 1876 | }; |
1878 | u8 config; | 1877 | u8 config; |
1879 | 1878 | ||
1880 | if (reset) | 1879 | if (reset) |
1881 | w83795_write(client, W83795_REG_CONFIG, 0x80); | 1880 | w83795_write(client, W83795_REG_CONFIG, 0x80); |
1882 | 1881 | ||
1883 | /* Start monitoring if needed */ | 1882 | /* Start monitoring if needed */ |
1884 | config = w83795_read(client, W83795_REG_CONFIG); | 1883 | config = w83795_read(client, W83795_REG_CONFIG); |
1885 | if (!(config & W83795_REG_CONFIG_START)) { | 1884 | if (!(config & W83795_REG_CONFIG_START)) { |
1886 | dev_info(&client->dev, "Enabling monitoring operations\n"); | 1885 | dev_info(&client->dev, "Enabling monitoring operations\n"); |
1887 | w83795_write(client, W83795_REG_CONFIG, | 1886 | w83795_write(client, W83795_REG_CONFIG, |
1888 | config | W83795_REG_CONFIG_START); | 1887 | config | W83795_REG_CONFIG_START); |
1889 | } | 1888 | } |
1890 | 1889 | ||
1891 | data->clkin = clkin[(config >> 3) & 0x3]; | 1890 | data->clkin = clkin[(config >> 3) & 0x3]; |
1892 | dev_dbg(&client->dev, "clkin = %u kHz\n", data->clkin); | 1891 | dev_dbg(&client->dev, "clkin = %u kHz\n", data->clkin); |
1893 | } | 1892 | } |
1894 | 1893 | ||
1895 | static int w83795_get_device_id(struct i2c_client *client) | 1894 | static int w83795_get_device_id(struct i2c_client *client) |
1896 | { | 1895 | { |
1897 | int device_id; | 1896 | int device_id; |
1898 | 1897 | ||
1899 | device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID); | 1898 | device_id = i2c_smbus_read_byte_data(client, W83795_REG_DEVICEID); |
1900 | 1899 | ||
1901 | /* | 1900 | /* |
1902 | * Special case for rev. A chips; can't be checked first because later | 1901 | * Special case for rev. A chips; can't be checked first because later |
1903 | * revisions emulate this for compatibility | 1902 | * revisions emulate this for compatibility |
1904 | */ | 1903 | */ |
1905 | if (device_id < 0 || (device_id & 0xf0) != 0x50) { | 1904 | if (device_id < 0 || (device_id & 0xf0) != 0x50) { |
1906 | int alt_id; | 1905 | int alt_id; |
1907 | 1906 | ||
1908 | alt_id = i2c_smbus_read_byte_data(client, | 1907 | alt_id = i2c_smbus_read_byte_data(client, |
1909 | W83795_REG_DEVICEID_A); | 1908 | W83795_REG_DEVICEID_A); |
1910 | if (alt_id == 0x50) | 1909 | if (alt_id == 0x50) |
1911 | device_id = alt_id; | 1910 | device_id = alt_id; |
1912 | } | 1911 | } |
1913 | 1912 | ||
1914 | return device_id; | 1913 | return device_id; |
1915 | } | 1914 | } |
1916 | 1915 | ||
1917 | /* Return 0 if detection is successful, -ENODEV otherwise */ | 1916 | /* Return 0 if detection is successful, -ENODEV otherwise */ |
1918 | static int w83795_detect(struct i2c_client *client, | 1917 | static int w83795_detect(struct i2c_client *client, |
1919 | struct i2c_board_info *info) | 1918 | struct i2c_board_info *info) |
1920 | { | 1919 | { |
1921 | int bank, vendor_id, device_id, expected, i2c_addr, config; | 1920 | int bank, vendor_id, device_id, expected, i2c_addr, config; |
1922 | struct i2c_adapter *adapter = client->adapter; | 1921 | struct i2c_adapter *adapter = client->adapter; |
1923 | unsigned short address = client->addr; | 1922 | unsigned short address = client->addr; |
1924 | const char *chip_name; | 1923 | const char *chip_name; |
1925 | 1924 | ||
1926 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | 1925 | if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) |
1927 | return -ENODEV; | 1926 | return -ENODEV; |
1928 | bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL); | 1927 | bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL); |
1929 | if (bank < 0 || (bank & 0x7c)) { | 1928 | if (bank < 0 || (bank & 0x7c)) { |
1930 | dev_dbg(&adapter->dev, | 1929 | dev_dbg(&adapter->dev, |
1931 | "w83795: Detection failed at addr 0x%02hx, check %s\n", | 1930 | "w83795: Detection failed at addr 0x%02hx, check %s\n", |
1932 | address, "bank"); | 1931 | address, "bank"); |
1933 | return -ENODEV; | 1932 | return -ENODEV; |
1934 | } | 1933 | } |
1935 | 1934 | ||
1936 | /* Check Nuvoton vendor ID */ | 1935 | /* Check Nuvoton vendor ID */ |
1937 | vendor_id = i2c_smbus_read_byte_data(client, W83795_REG_VENDORID); | 1936 | vendor_id = i2c_smbus_read_byte_data(client, W83795_REG_VENDORID); |
1938 | expected = bank & 0x80 ? 0x5c : 0xa3; | 1937 | expected = bank & 0x80 ? 0x5c : 0xa3; |
1939 | if (vendor_id != expected) { | 1938 | if (vendor_id != expected) { |
1940 | dev_dbg(&adapter->dev, | 1939 | dev_dbg(&adapter->dev, |
1941 | "w83795: Detection failed at addr 0x%02hx, check %s\n", | 1940 | "w83795: Detection failed at addr 0x%02hx, check %s\n", |
1942 | address, "vendor id"); | 1941 | address, "vendor id"); |
1943 | return -ENODEV; | 1942 | return -ENODEV; |
1944 | } | 1943 | } |
1945 | 1944 | ||
1946 | /* Check device ID */ | 1945 | /* Check device ID */ |
1947 | device_id = w83795_get_device_id(client) | | 1946 | device_id = w83795_get_device_id(client) | |
1948 | (i2c_smbus_read_byte_data(client, W83795_REG_CHIPID) << 8); | 1947 | (i2c_smbus_read_byte_data(client, W83795_REG_CHIPID) << 8); |
1949 | if ((device_id >> 4) != 0x795) { | 1948 | if ((device_id >> 4) != 0x795) { |
1950 | dev_dbg(&adapter->dev, | 1949 | dev_dbg(&adapter->dev, |
1951 | "w83795: Detection failed at addr 0x%02hx, check %s\n", | 1950 | "w83795: Detection failed at addr 0x%02hx, check %s\n", |
1952 | address, "device id\n"); | 1951 | address, "device id\n"); |
1953 | return -ENODEV; | 1952 | return -ENODEV; |
1954 | } | 1953 | } |
1955 | 1954 | ||
1956 | /* | 1955 | /* |
1957 | * If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR | 1956 | * If Nuvoton chip, address of chip and W83795_REG_I2C_ADDR |
1958 | * should match | 1957 | * should match |
1959 | */ | 1958 | */ |
1960 | if ((bank & 0x07) == 0) { | 1959 | if ((bank & 0x07) == 0) { |
1961 | i2c_addr = i2c_smbus_read_byte_data(client, | 1960 | i2c_addr = i2c_smbus_read_byte_data(client, |
1962 | W83795_REG_I2C_ADDR); | 1961 | W83795_REG_I2C_ADDR); |
1963 | if ((i2c_addr & 0x7f) != address) { | 1962 | if ((i2c_addr & 0x7f) != address) { |
1964 | dev_dbg(&adapter->dev, | 1963 | dev_dbg(&adapter->dev, |
1965 | "w83795: Detection failed at addr 0x%02hx, " | 1964 | "w83795: Detection failed at addr 0x%02hx, " |
1966 | "check %s\n", address, "i2c addr"); | 1965 | "check %s\n", address, "i2c addr"); |
1967 | return -ENODEV; | 1966 | return -ENODEV; |
1968 | } | 1967 | } |
1969 | } | 1968 | } |
1970 | 1969 | ||
1971 | /* | 1970 | /* |
1972 | * Check 795 chip type: 795G or 795ADG | 1971 | * Check 795 chip type: 795G or 795ADG |
1973 | * Usually we don't write to chips during detection, but here we don't | 1972 | * Usually we don't write to chips during detection, but here we don't |
1974 | * quite have the choice; hopefully it's OK, we are about to return | 1973 | * quite have the choice; hopefully it's OK, we are about to return |
1975 | * success anyway | 1974 | * success anyway |
1976 | */ | 1975 | */ |
1977 | if ((bank & 0x07) != 0) | 1976 | if ((bank & 0x07) != 0) |
1978 | i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, | 1977 | i2c_smbus_write_byte_data(client, W83795_REG_BANKSEL, |
1979 | bank & ~0x07); | 1978 | bank & ~0x07); |
1980 | config = i2c_smbus_read_byte_data(client, W83795_REG_CONFIG); | 1979 | config = i2c_smbus_read_byte_data(client, W83795_REG_CONFIG); |
1981 | if (config & W83795_REG_CONFIG_CONFIG48) | 1980 | if (config & W83795_REG_CONFIG_CONFIG48) |
1982 | chip_name = "w83795adg"; | 1981 | chip_name = "w83795adg"; |
1983 | else | 1982 | else |
1984 | chip_name = "w83795g"; | 1983 | chip_name = "w83795g"; |
1985 | 1984 | ||
1986 | strlcpy(info->type, chip_name, I2C_NAME_SIZE); | 1985 | strlcpy(info->type, chip_name, I2C_NAME_SIZE); |
1987 | dev_info(&adapter->dev, "Found %s rev. %c at 0x%02hx\n", chip_name, | 1986 | dev_info(&adapter->dev, "Found %s rev. %c at 0x%02hx\n", chip_name, |
1988 | 'A' + (device_id & 0xf), address); | 1987 | 'A' + (device_id & 0xf), address); |
1989 | 1988 | ||
1990 | return 0; | 1989 | return 0; |
1991 | } | 1990 | } |
1992 | 1991 | ||
1993 | #ifdef CONFIG_SENSORS_W83795_FANCTRL | 1992 | #ifdef CONFIG_SENSORS_W83795_FANCTRL |
1994 | #define NUM_PWM_ATTRIBUTES ARRAY_SIZE(w83795_pwm[0]) | 1993 | #define NUM_PWM_ATTRIBUTES ARRAY_SIZE(w83795_pwm[0]) |
1995 | #define NUM_TEMP_ATTRIBUTES ARRAY_SIZE(w83795_temp[0]) | 1994 | #define NUM_TEMP_ATTRIBUTES ARRAY_SIZE(w83795_temp[0]) |
1996 | #else | 1995 | #else |
1997 | #define NUM_PWM_ATTRIBUTES 4 | 1996 | #define NUM_PWM_ATTRIBUTES 4 |
1998 | #define NUM_TEMP_ATTRIBUTES 8 | 1997 | #define NUM_TEMP_ATTRIBUTES 8 |
1999 | #endif | 1998 | #endif |
2000 | 1999 | ||
2001 | static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, | 2000 | static int w83795_handle_files(struct device *dev, int (*fn)(struct device *, |
2002 | const struct device_attribute *)) | 2001 | const struct device_attribute *)) |
2003 | { | 2002 | { |
2004 | struct w83795_data *data = dev_get_drvdata(dev); | 2003 | struct w83795_data *data = dev_get_drvdata(dev); |
2005 | int err, i, j; | 2004 | int err, i, j; |
2006 | 2005 | ||
2007 | for (i = 0; i < ARRAY_SIZE(w83795_in); i++) { | 2006 | for (i = 0; i < ARRAY_SIZE(w83795_in); i++) { |
2008 | if (!(data->has_in & (1 << i))) | 2007 | if (!(data->has_in & (1 << i))) |
2009 | continue; | 2008 | continue; |
2010 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { | 2009 | for (j = 0; j < ARRAY_SIZE(w83795_in[0]); j++) { |
2011 | if (j == 4 && !data->enable_beep) | 2010 | if (j == 4 && !data->enable_beep) |
2012 | continue; | 2011 | continue; |
2013 | err = fn(dev, &w83795_in[i][j].dev_attr); | 2012 | err = fn(dev, &w83795_in[i][j].dev_attr); |
2014 | if (err) | 2013 | if (err) |
2015 | return err; | 2014 | return err; |
2016 | } | 2015 | } |
2017 | } | 2016 | } |
2018 | 2017 | ||
2019 | for (i = 0; i < ARRAY_SIZE(w83795_fan); i++) { | 2018 | for (i = 0; i < ARRAY_SIZE(w83795_fan); i++) { |
2020 | if (!(data->has_fan & (1 << i))) | 2019 | if (!(data->has_fan & (1 << i))) |
2021 | continue; | 2020 | continue; |
2022 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { | 2021 | for (j = 0; j < ARRAY_SIZE(w83795_fan[0]); j++) { |
2023 | if (j == 3 && !data->enable_beep) | 2022 | if (j == 3 && !data->enable_beep) |
2024 | continue; | 2023 | continue; |
2025 | err = fn(dev, &w83795_fan[i][j].dev_attr); | 2024 | err = fn(dev, &w83795_fan[i][j].dev_attr); |
2026 | if (err) | 2025 | if (err) |
2027 | return err; | 2026 | return err; |
2028 | } | 2027 | } |
2029 | } | 2028 | } |
2030 | 2029 | ||
2031 | for (i = 0; i < ARRAY_SIZE(w83795_tss); i++) { | 2030 | for (i = 0; i < ARRAY_SIZE(w83795_tss); i++) { |
2032 | j = w83795_tss_useful(data, i); | 2031 | j = w83795_tss_useful(data, i); |
2033 | if (!j) | 2032 | if (!j) |
2034 | continue; | 2033 | continue; |
2035 | err = fn(dev, &w83795_tss[i].dev_attr); | 2034 | err = fn(dev, &w83795_tss[i].dev_attr); |
2036 | if (err) | 2035 | if (err) |
2037 | return err; | 2036 | return err; |
2038 | } | 2037 | } |
2039 | 2038 | ||
2040 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { | 2039 | for (i = 0; i < ARRAY_SIZE(sda_single_files); i++) { |
2041 | err = fn(dev, &sda_single_files[i].dev_attr); | 2040 | err = fn(dev, &sda_single_files[i].dev_attr); |
2042 | if (err) | 2041 | if (err) |
2043 | return err; | 2042 | return err; |
2044 | } | 2043 | } |
2045 | 2044 | ||
2046 | if (data->enable_beep) { | 2045 | if (data->enable_beep) { |
2047 | for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) { | 2046 | for (i = 0; i < ARRAY_SIZE(sda_beep_files); i++) { |
2048 | err = fn(dev, &sda_beep_files[i].dev_attr); | 2047 | err = fn(dev, &sda_beep_files[i].dev_attr); |
2049 | if (err) | 2048 | if (err) |
2050 | return err; | 2049 | return err; |
2051 | } | 2050 | } |
2052 | } | 2051 | } |
2053 | 2052 | ||
2054 | for (i = 0; i < data->has_pwm; i++) { | 2053 | for (i = 0; i < data->has_pwm; i++) { |
2055 | for (j = 0; j < NUM_PWM_ATTRIBUTES; j++) { | 2054 | for (j = 0; j < NUM_PWM_ATTRIBUTES; j++) { |
2056 | err = fn(dev, &w83795_pwm[i][j].dev_attr); | 2055 | err = fn(dev, &w83795_pwm[i][j].dev_attr); |
2057 | if (err) | 2056 | if (err) |
2058 | return err; | 2057 | return err; |
2059 | } | 2058 | } |
2060 | } | 2059 | } |
2061 | 2060 | ||
2062 | for (i = 0; i < ARRAY_SIZE(w83795_temp); i++) { | 2061 | for (i = 0; i < ARRAY_SIZE(w83795_temp); i++) { |
2063 | if (!(data->has_temp & (1 << i))) | 2062 | if (!(data->has_temp & (1 << i))) |
2064 | continue; | 2063 | continue; |
2065 | for (j = 0; j < NUM_TEMP_ATTRIBUTES; j++) { | 2064 | for (j = 0; j < NUM_TEMP_ATTRIBUTES; j++) { |
2066 | if (j == 7 && !data->enable_beep) | 2065 | if (j == 7 && !data->enable_beep) |
2067 | continue; | 2066 | continue; |
2068 | err = fn(dev, &w83795_temp[i][j].dev_attr); | 2067 | err = fn(dev, &w83795_temp[i][j].dev_attr); |
2069 | if (err) | 2068 | if (err) |
2070 | return err; | 2069 | return err; |
2071 | } | 2070 | } |
2072 | } | 2071 | } |
2073 | 2072 | ||
2074 | if (data->enable_dts) { | 2073 | if (data->enable_dts) { |
2075 | for (i = 0; i < ARRAY_SIZE(w83795_dts); i++) { | 2074 | for (i = 0; i < ARRAY_SIZE(w83795_dts); i++) { |
2076 | if (!(data->has_dts & (1 << i))) | 2075 | if (!(data->has_dts & (1 << i))) |
2077 | continue; | 2076 | continue; |
2078 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { | 2077 | for (j = 0; j < ARRAY_SIZE(w83795_dts[0]); j++) { |
2079 | if (j == 7 && !data->enable_beep) | 2078 | if (j == 7 && !data->enable_beep) |
2080 | continue; | 2079 | continue; |
2081 | err = fn(dev, &w83795_dts[i][j].dev_attr); | 2080 | err = fn(dev, &w83795_dts[i][j].dev_attr); |
2082 | if (err) | 2081 | if (err) |
2083 | return err; | 2082 | return err; |
2084 | } | 2083 | } |
2085 | } | 2084 | } |
2086 | } | 2085 | } |
2087 | 2086 | ||
2088 | return 0; | 2087 | return 0; |
2089 | } | 2088 | } |
2090 | 2089 | ||
2091 | /* We need a wrapper that fits in w83795_handle_files */ | 2090 | /* We need a wrapper that fits in w83795_handle_files */ |
2092 | static int device_remove_file_wrapper(struct device *dev, | 2091 | static int device_remove_file_wrapper(struct device *dev, |
2093 | const struct device_attribute *attr) | 2092 | const struct device_attribute *attr) |
2094 | { | 2093 | { |
2095 | device_remove_file(dev, attr); | 2094 | device_remove_file(dev, attr); |
2096 | return 0; | 2095 | return 0; |
2097 | } | 2096 | } |
2098 | 2097 | ||
2099 | static void w83795_check_dynamic_in_limits(struct i2c_client *client) | 2098 | static void w83795_check_dynamic_in_limits(struct i2c_client *client) |
2100 | { | 2099 | { |
2101 | struct w83795_data *data = i2c_get_clientdata(client); | 2100 | struct w83795_data *data = i2c_get_clientdata(client); |
2102 | u8 vid_ctl; | 2101 | u8 vid_ctl; |
2103 | int i, err_max, err_min; | 2102 | int i, err_max, err_min; |
2104 | 2103 | ||
2105 | vid_ctl = w83795_read(client, W83795_REG_VID_CTRL); | 2104 | vid_ctl = w83795_read(client, W83795_REG_VID_CTRL); |
2106 | 2105 | ||
2107 | /* Return immediately if VRM isn't configured */ | 2106 | /* Return immediately if VRM isn't configured */ |
2108 | if ((vid_ctl & 0x07) == 0x00 || (vid_ctl & 0x07) == 0x07) | 2107 | if ((vid_ctl & 0x07) == 0x00 || (vid_ctl & 0x07) == 0x07) |
2109 | return; | 2108 | return; |
2110 | 2109 | ||
2111 | data->has_dyn_in = (vid_ctl >> 3) & 0x07; | 2110 | data->has_dyn_in = (vid_ctl >> 3) & 0x07; |
2112 | for (i = 0; i < 2; i++) { | 2111 | for (i = 0; i < 2; i++) { |
2113 | if (!(data->has_dyn_in & (1 << i))) | 2112 | if (!(data->has_dyn_in & (1 << i))) |
2114 | continue; | 2113 | continue; |
2115 | 2114 | ||
2116 | /* Voltage limits in dynamic mode, switch to read-only */ | 2115 | /* Voltage limits in dynamic mode, switch to read-only */ |
2117 | err_max = sysfs_chmod_file(&client->dev.kobj, | 2116 | err_max = sysfs_chmod_file(&client->dev.kobj, |
2118 | &w83795_in[i][2].dev_attr.attr, | 2117 | &w83795_in[i][2].dev_attr.attr, |
2119 | S_IRUGO); | 2118 | S_IRUGO); |
2120 | err_min = sysfs_chmod_file(&client->dev.kobj, | 2119 | err_min = sysfs_chmod_file(&client->dev.kobj, |
2121 | &w83795_in[i][3].dev_attr.attr, | 2120 | &w83795_in[i][3].dev_attr.attr, |
2122 | S_IRUGO); | 2121 | S_IRUGO); |
2123 | if (err_max || err_min) | 2122 | if (err_max || err_min) |
2124 | dev_warn(&client->dev, "Failed to set in%d limits " | 2123 | dev_warn(&client->dev, "Failed to set in%d limits " |
2125 | "read-only (%d, %d)\n", i, err_max, err_min); | 2124 | "read-only (%d, %d)\n", i, err_max, err_min); |
2126 | else | 2125 | else |
2127 | dev_info(&client->dev, "in%d limits set dynamically " | 2126 | dev_info(&client->dev, "in%d limits set dynamically " |
2128 | "from VID\n", i); | 2127 | "from VID\n", i); |
2129 | } | 2128 | } |
2130 | } | 2129 | } |
2131 | 2130 | ||
2132 | /* Check pins that can be used for either temperature or voltage monitoring */ | 2131 | /* Check pins that can be used for either temperature or voltage monitoring */ |
2133 | static void w83795_apply_temp_config(struct w83795_data *data, u8 config, | 2132 | static void w83795_apply_temp_config(struct w83795_data *data, u8 config, |
2134 | int temp_chan, int in_chan) | 2133 | int temp_chan, int in_chan) |
2135 | { | 2134 | { |
2136 | /* config is a 2-bit value */ | 2135 | /* config is a 2-bit value */ |
2137 | switch (config) { | 2136 | switch (config) { |
2138 | case 0x2: /* Voltage monitoring */ | 2137 | case 0x2: /* Voltage monitoring */ |
2139 | data->has_in |= 1 << in_chan; | 2138 | data->has_in |= 1 << in_chan; |
2140 | break; | 2139 | break; |
2141 | case 0x1: /* Thermal diode */ | 2140 | case 0x1: /* Thermal diode */ |
2142 | if (temp_chan >= 4) | 2141 | if (temp_chan >= 4) |
2143 | break; | 2142 | break; |
2144 | data->temp_mode |= 1 << temp_chan; | 2143 | data->temp_mode |= 1 << temp_chan; |
2145 | /* fall through */ | 2144 | /* fall through */ |
2146 | case 0x3: /* Thermistor */ | 2145 | case 0x3: /* Thermistor */ |
2147 | data->has_temp |= 1 << temp_chan; | 2146 | data->has_temp |= 1 << temp_chan; |
2148 | break; | 2147 | break; |
2149 | } | 2148 | } |
2150 | } | 2149 | } |
2151 | 2150 | ||
2152 | static int w83795_probe(struct i2c_client *client, | 2151 | static int w83795_probe(struct i2c_client *client, |
2153 | const struct i2c_device_id *id) | 2152 | const struct i2c_device_id *id) |
2154 | { | 2153 | { |
2155 | int i; | 2154 | int i; |
2156 | u8 tmp; | 2155 | u8 tmp; |
2157 | struct device *dev = &client->dev; | 2156 | struct device *dev = &client->dev; |
2158 | struct w83795_data *data; | 2157 | struct w83795_data *data; |
2159 | int err; | 2158 | int err; |
2160 | 2159 | ||
2161 | data = devm_kzalloc(dev, sizeof(struct w83795_data), GFP_KERNEL); | 2160 | data = devm_kzalloc(dev, sizeof(struct w83795_data), GFP_KERNEL); |
2162 | if (!data) | 2161 | if (!data) |
2163 | return -ENOMEM; | 2162 | return -ENOMEM; |
2164 | 2163 | ||
2165 | i2c_set_clientdata(client, data); | 2164 | i2c_set_clientdata(client, data); |
2166 | data->chip_type = id->driver_data; | 2165 | data->chip_type = id->driver_data; |
2167 | data->bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL); | 2166 | data->bank = i2c_smbus_read_byte_data(client, W83795_REG_BANKSEL); |
2168 | mutex_init(&data->update_lock); | 2167 | mutex_init(&data->update_lock); |
2169 | 2168 | ||
2170 | /* Initialize the chip */ | 2169 | /* Initialize the chip */ |
2171 | w83795_init_client(client); | 2170 | w83795_init_client(client); |
2172 | 2171 | ||
2173 | /* Check which voltages and fans are present */ | 2172 | /* Check which voltages and fans are present */ |
2174 | data->has_in = w83795_read(client, W83795_REG_VOLT_CTRL1) | 2173 | data->has_in = w83795_read(client, W83795_REG_VOLT_CTRL1) |
2175 | | (w83795_read(client, W83795_REG_VOLT_CTRL2) << 8); | 2174 | | (w83795_read(client, W83795_REG_VOLT_CTRL2) << 8); |
2176 | data->has_fan = w83795_read(client, W83795_REG_FANIN_CTRL1) | 2175 | data->has_fan = w83795_read(client, W83795_REG_FANIN_CTRL1) |
2177 | | (w83795_read(client, W83795_REG_FANIN_CTRL2) << 8); | 2176 | | (w83795_read(client, W83795_REG_FANIN_CTRL2) << 8); |
2178 | 2177 | ||
2179 | /* Check which analog temperatures and extra voltages are present */ | 2178 | /* Check which analog temperatures and extra voltages are present */ |
2180 | tmp = w83795_read(client, W83795_REG_TEMP_CTRL1); | 2179 | tmp = w83795_read(client, W83795_REG_TEMP_CTRL1); |
2181 | if (tmp & 0x20) | 2180 | if (tmp & 0x20) |
2182 | data->enable_dts = 1; | 2181 | data->enable_dts = 1; |
2183 | w83795_apply_temp_config(data, (tmp >> 2) & 0x3, 5, 16); | 2182 | w83795_apply_temp_config(data, (tmp >> 2) & 0x3, 5, 16); |
2184 | w83795_apply_temp_config(data, tmp & 0x3, 4, 15); | 2183 | w83795_apply_temp_config(data, tmp & 0x3, 4, 15); |
2185 | tmp = w83795_read(client, W83795_REG_TEMP_CTRL2); | 2184 | tmp = w83795_read(client, W83795_REG_TEMP_CTRL2); |
2186 | w83795_apply_temp_config(data, tmp >> 6, 3, 20); | 2185 | w83795_apply_temp_config(data, tmp >> 6, 3, 20); |
2187 | w83795_apply_temp_config(data, (tmp >> 4) & 0x3, 2, 19); | 2186 | w83795_apply_temp_config(data, (tmp >> 4) & 0x3, 2, 19); |
2188 | w83795_apply_temp_config(data, (tmp >> 2) & 0x3, 1, 18); | 2187 | w83795_apply_temp_config(data, (tmp >> 2) & 0x3, 1, 18); |
2189 | w83795_apply_temp_config(data, tmp & 0x3, 0, 17); | 2188 | w83795_apply_temp_config(data, tmp & 0x3, 0, 17); |
2190 | 2189 | ||
2191 | /* Check DTS enable status */ | 2190 | /* Check DTS enable status */ |
2192 | if (data->enable_dts) { | 2191 | if (data->enable_dts) { |
2193 | if (1 & w83795_read(client, W83795_REG_DTSC)) | 2192 | if (1 & w83795_read(client, W83795_REG_DTSC)) |
2194 | data->enable_dts |= 2; | 2193 | data->enable_dts |= 2; |
2195 | data->has_dts = w83795_read(client, W83795_REG_DTSE); | 2194 | data->has_dts = w83795_read(client, W83795_REG_DTSE); |
2196 | } | 2195 | } |
2197 | 2196 | ||
2198 | /* Report PECI Tbase values */ | 2197 | /* Report PECI Tbase values */ |
2199 | if (data->enable_dts == 1) { | 2198 | if (data->enable_dts == 1) { |
2200 | for (i = 0; i < 8; i++) { | 2199 | for (i = 0; i < 8; i++) { |
2201 | if (!(data->has_dts & (1 << i))) | 2200 | if (!(data->has_dts & (1 << i))) |
2202 | continue; | 2201 | continue; |
2203 | tmp = w83795_read(client, W83795_REG_PECI_TBASE(i)); | 2202 | tmp = w83795_read(client, W83795_REG_PECI_TBASE(i)); |
2204 | dev_info(&client->dev, | 2203 | dev_info(&client->dev, |
2205 | "PECI agent %d Tbase temperature: %u\n", | 2204 | "PECI agent %d Tbase temperature: %u\n", |
2206 | i + 1, (unsigned int)tmp & 0x7f); | 2205 | i + 1, (unsigned int)tmp & 0x7f); |
2207 | } | 2206 | } |
2208 | } | 2207 | } |
2209 | 2208 | ||
2210 | data->has_gain = w83795_read(client, W83795_REG_VMIGB_CTRL) & 0x0f; | 2209 | data->has_gain = w83795_read(client, W83795_REG_VMIGB_CTRL) & 0x0f; |
2211 | 2210 | ||
2212 | /* pwm and smart fan */ | 2211 | /* pwm and smart fan */ |
2213 | if (data->chip_type == w83795g) | 2212 | if (data->chip_type == w83795g) |
2214 | data->has_pwm = 8; | 2213 | data->has_pwm = 8; |
2215 | else | 2214 | else |
2216 | data->has_pwm = 2; | 2215 | data->has_pwm = 2; |
2217 | 2216 | ||
2218 | /* Check if BEEP pin is available */ | 2217 | /* Check if BEEP pin is available */ |
2219 | if (data->chip_type == w83795g) { | 2218 | if (data->chip_type == w83795g) { |
2220 | /* The W83795G has a dedicated BEEP pin */ | 2219 | /* The W83795G has a dedicated BEEP pin */ |
2221 | data->enable_beep = 1; | 2220 | data->enable_beep = 1; |
2222 | } else { | 2221 | } else { |
2223 | /* | 2222 | /* |
2224 | * The W83795ADG has a shared pin for OVT# and BEEP, so you | 2223 | * The W83795ADG has a shared pin for OVT# and BEEP, so you |
2225 | * can't have both | 2224 | * can't have both |
2226 | */ | 2225 | */ |
2227 | tmp = w83795_read(client, W83795_REG_OVT_CFG); | 2226 | tmp = w83795_read(client, W83795_REG_OVT_CFG); |
2228 | if ((tmp & OVT_CFG_SEL) == 0) | 2227 | if ((tmp & OVT_CFG_SEL) == 0) |
2229 | data->enable_beep = 1; | 2228 | data->enable_beep = 1; |
2230 | } | 2229 | } |
2231 | 2230 | ||
2232 | err = w83795_handle_files(dev, device_create_file); | 2231 | err = w83795_handle_files(dev, device_create_file); |
2233 | if (err) | 2232 | if (err) |
2234 | goto exit_remove; | 2233 | goto exit_remove; |
2235 | 2234 | ||
2236 | if (data->chip_type == w83795g) | 2235 | if (data->chip_type == w83795g) |
2237 | w83795_check_dynamic_in_limits(client); | 2236 | w83795_check_dynamic_in_limits(client); |
2238 | 2237 | ||
2239 | data->hwmon_dev = hwmon_device_register(dev); | 2238 | data->hwmon_dev = hwmon_device_register(dev); |
2240 | if (IS_ERR(data->hwmon_dev)) { | 2239 | if (IS_ERR(data->hwmon_dev)) { |
2241 | err = PTR_ERR(data->hwmon_dev); | 2240 | err = PTR_ERR(data->hwmon_dev); |
2242 | goto exit_remove; | 2241 | goto exit_remove; |
2243 | } | 2242 | } |
2244 | 2243 | ||
2245 | return 0; | 2244 | return 0; |
2246 | 2245 | ||
2247 | exit_remove: | 2246 | exit_remove: |
2248 | w83795_handle_files(dev, device_remove_file_wrapper); | 2247 | w83795_handle_files(dev, device_remove_file_wrapper); |
2249 | return err; | 2248 | return err; |
2250 | } | 2249 | } |
2251 | 2250 | ||
2252 | static int w83795_remove(struct i2c_client *client) | 2251 | static int w83795_remove(struct i2c_client *client) |
2253 | { | 2252 | { |
2254 | struct w83795_data *data = i2c_get_clientdata(client); | 2253 | struct w83795_data *data = i2c_get_clientdata(client); |
2255 | 2254 | ||
2256 | hwmon_device_unregister(data->hwmon_dev); | 2255 | hwmon_device_unregister(data->hwmon_dev); |
2257 | w83795_handle_files(&client->dev, device_remove_file_wrapper); | 2256 | w83795_handle_files(&client->dev, device_remove_file_wrapper); |
2258 | 2257 | ||
2259 | return 0; | 2258 | return 0; |
2260 | } | 2259 | } |
2261 | 2260 | ||
2262 | 2261 | ||
2263 | static const struct i2c_device_id w83795_id[] = { | 2262 | static const struct i2c_device_id w83795_id[] = { |
2264 | { "w83795g", w83795g }, | 2263 | { "w83795g", w83795g }, |
2265 | { "w83795adg", w83795adg }, | 2264 | { "w83795adg", w83795adg }, |
2266 | { } | 2265 | { } |
2267 | }; | 2266 | }; |
2268 | MODULE_DEVICE_TABLE(i2c, w83795_id); | 2267 | MODULE_DEVICE_TABLE(i2c, w83795_id); |
2269 | 2268 | ||
2270 | static struct i2c_driver w83795_driver = { | 2269 | static struct i2c_driver w83795_driver = { |
2271 | .driver = { | 2270 | .driver = { |
2272 | .name = "w83795", | 2271 | .name = "w83795", |
2273 | }, | 2272 | }, |
2274 | .probe = w83795_probe, | 2273 | .probe = w83795_probe, |
2275 | .remove = w83795_remove, | 2274 | .remove = w83795_remove, |
2276 | .id_table = w83795_id, | 2275 | .id_table = w83795_id, |
2277 | 2276 | ||
2278 | .class = I2C_CLASS_HWMON, | 2277 | .class = I2C_CLASS_HWMON, |
2279 | .detect = w83795_detect, | 2278 | .detect = w83795_detect, |
2280 | .address_list = normal_i2c, | 2279 | .address_list = normal_i2c, |
2281 | }; | 2280 | }; |
2282 | 2281 | ||
2283 | module_i2c_driver(w83795_driver); | 2282 | module_i2c_driver(w83795_driver); |
2284 | 2283 | ||
2285 | MODULE_AUTHOR("Wei Song, Jean Delvare <khali@linux-fr.org>"); | 2284 | MODULE_AUTHOR("Wei Song, Jean Delvare <khali@linux-fr.org>"); |
2286 | MODULE_DESCRIPTION("W83795G/ADG hardware monitoring driver"); | 2285 | MODULE_DESCRIPTION("W83795G/ADG hardware monitoring driver"); |
2287 | MODULE_LICENSE("GPL"); | 2286 | MODULE_LICENSE("GPL"); |
2288 | 2287 |