aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/smsc47m1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/smsc47m1.c')
-rw-r--r--drivers/hwmon/smsc47m1.c606
1 files changed, 367 insertions, 239 deletions
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index beb881c4b2e8..1e21c8cc948f 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -3,10 +3,11 @@
3 for hardware monitoring 3 for hardware monitoring
4 4
5 Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x, 5 Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
6 LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips. 6 LPC47M14x, LPC47M15x, LPC47M192, LPC47M292 and LPC47M997
7 Super-I/O chips.
7 8
8 Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com> 9 Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
9 Copyright (C) 2004 Jean Delvare <khali@linux-fr.org> 10 Copyright (C) 2004-2007 Jean Delvare <khali@linux-fr.org>
10 Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com> 11 Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
11 and Jean Delvare 12 and Jean Delvare
12 13
@@ -29,17 +30,19 @@
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/ioport.h> 31#include <linux/ioport.h>
31#include <linux/jiffies.h> 32#include <linux/jiffies.h>
32#include <linux/i2c.h> 33#include <linux/platform_device.h>
33#include <linux/i2c-isa.h>
34#include <linux/hwmon.h> 34#include <linux/hwmon.h>
35#include <linux/hwmon-sysfs.h>
35#include <linux/err.h> 36#include <linux/err.h>
36#include <linux/init.h> 37#include <linux/init.h>
37#include <linux/mutex.h> 38#include <linux/mutex.h>
38#include <linux/sysfs.h> 39#include <linux/sysfs.h>
39#include <asm/io.h> 40#include <asm/io.h>
40 41
41/* Address is autodetected, there is no default value */ 42static struct platform_device *pdev;
42static unsigned short address; 43
44#define DRVNAME "smsc47m1"
45enum chips { smsc47m1, smsc47m2 };
43 46
44/* Super-I/0 registers and commands */ 47/* Super-I/0 registers and commands */
45 48
@@ -87,10 +90,18 @@ superio_exit(void)
87#define SMSC47M1_REG_ALARM 0x04 90#define SMSC47M1_REG_ALARM 0x04
88#define SMSC47M1_REG_TPIN(nr) (0x34 - (nr)) 91#define SMSC47M1_REG_TPIN(nr) (0x34 - (nr))
89#define SMSC47M1_REG_PPIN(nr) (0x36 - (nr)) 92#define SMSC47M1_REG_PPIN(nr) (0x36 - (nr))
90#define SMSC47M1_REG_PWM(nr) (0x56 + (nr))
91#define SMSC47M1_REG_FANDIV 0x58 93#define SMSC47M1_REG_FANDIV 0x58
92#define SMSC47M1_REG_FAN(nr) (0x59 + (nr)) 94
93#define SMSC47M1_REG_FAN_PRELOAD(nr) (0x5B + (nr)) 95static const u8 SMSC47M1_REG_FAN[3] = { 0x59, 0x5a, 0x6b };
96static const u8 SMSC47M1_REG_FAN_PRELOAD[3] = { 0x5b, 0x5c, 0x6c };
97static const u8 SMSC47M1_REG_PWM[3] = { 0x56, 0x57, 0x69 };
98
99#define SMSC47M2_REG_ALARM6 0x09
100#define SMSC47M2_REG_TPIN1 0x38
101#define SMSC47M2_REG_TPIN2 0x37
102#define SMSC47M2_REG_TPIN3 0x2d
103#define SMSC47M2_REG_PPIN3 0x2c
104#define SMSC47M2_REG_FANDIV3 0x6a
94 105
95#define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \ 106#define MIN_FROM_REG(reg,div) ((reg)>=192 ? 0 : \
96 983040/((192-(reg))*(div))) 107 983040/((192-(reg))*(div)))
@@ -102,45 +113,57 @@ superio_exit(void)
102#define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E) 113#define PWM_TO_REG(reg) (((reg) >> 1) & 0x7E)
103 114
104struct smsc47m1_data { 115struct smsc47m1_data {
105 struct i2c_client client; 116 unsigned short addr;
117 const char *name;
118 enum chips type;
106 struct class_device *class_dev; 119 struct class_device *class_dev;
107 struct mutex lock;
108 120
109 struct mutex update_lock; 121 struct mutex update_lock;
110 unsigned long last_updated; /* In jiffies */ 122 unsigned long last_updated; /* In jiffies */
111 123
112 u8 fan[2]; /* Register value */ 124 u8 fan[3]; /* Register value */
113 u8 fan_preload[2]; /* Register value */ 125 u8 fan_preload[3]; /* Register value */
114 u8 fan_div[2]; /* Register encoding, shifted right */ 126 u8 fan_div[3]; /* Register encoding, shifted right */
115 u8 alarms; /* Register encoding */ 127 u8 alarms; /* Register encoding */
116 u8 pwm[2]; /* Register value (bit 7 is enable) */ 128 u8 pwm[3]; /* Register value (bit 0 is disable) */
117}; 129};
118 130
131struct smsc47m1_sio_data {
132 enum chips type;
133};
119 134
120static int smsc47m1_detect(struct i2c_adapter *adapter);
121static int smsc47m1_detach_client(struct i2c_client *client);
122
123static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
124static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value);
125 135
136static int smsc47m1_probe(struct platform_device *pdev);
137static int smsc47m1_remove(struct platform_device *pdev);
126static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 138static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
127 int init); 139 int init);
128 140
141static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
142{
143 return inb_p(data->addr + reg);
144}
129 145
130static struct i2c_driver smsc47m1_driver = { 146static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg,
147 u8 value)
148{
149 outb_p(value, data->addr + reg);
150}
151
152static struct platform_driver smsc47m1_driver = {
131 .driver = { 153 .driver = {
132 .owner = THIS_MODULE, 154 .owner = THIS_MODULE,
133 .name = "smsc47m1", 155 .name = DRVNAME,
134 }, 156 },
135 .attach_adapter = smsc47m1_detect, 157 .probe = smsc47m1_probe,
136 .detach_client = smsc47m1_detach_client, 158 .remove = __devexit_p(smsc47m1_remove),
137}; 159};
138 160
139/* nr is 0 or 1 in the callback functions below */ 161static ssize_t get_fan(struct device *dev, struct device_attribute
140 162 *devattr, char *buf)
141static ssize_t get_fan(struct device *dev, char *buf, int nr)
142{ 163{
164 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
143 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 165 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
166 int nr = attr->index;
144 /* This chip (stupidly) stops monitoring fan speed if PWM is 167 /* This chip (stupidly) stops monitoring fan speed if PWM is
145 enabled and duty cycle is 0%. This is fine if the monitoring 168 enabled and duty cycle is 0%. This is fine if the monitoring
146 and control concern the same fan, but troublesome if they are 169 and control concern the same fan, but troublesome if they are
@@ -152,43 +175,54 @@ static ssize_t get_fan(struct device *dev, char *buf, int nr)
152 return sprintf(buf, "%d\n", rpm); 175 return sprintf(buf, "%d\n", rpm);
153} 176}
154 177
155static ssize_t get_fan_min(struct device *dev, char *buf, int nr) 178static ssize_t get_fan_min(struct device *dev, struct device_attribute
179 *devattr, char *buf)
156{ 180{
181 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
157 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 182 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
183 int nr = attr->index;
158 int rpm = MIN_FROM_REG(data->fan_preload[nr], 184 int rpm = MIN_FROM_REG(data->fan_preload[nr],
159 DIV_FROM_REG(data->fan_div[nr])); 185 DIV_FROM_REG(data->fan_div[nr]));
160 return sprintf(buf, "%d\n", rpm); 186 return sprintf(buf, "%d\n", rpm);
161} 187}
162 188
163static ssize_t get_fan_div(struct device *dev, char *buf, int nr) 189static ssize_t get_fan_div(struct device *dev, struct device_attribute
190 *devattr, char *buf)
164{ 191{
192 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
165 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 193 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
166 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr])); 194 return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
167} 195}
168 196
169static ssize_t get_pwm(struct device *dev, char *buf, int nr) 197static ssize_t get_pwm(struct device *dev, struct device_attribute
198 *devattr, char *buf)
170{ 199{
200 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
171 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 201 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
172 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr])); 202 return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[attr->index]));
173} 203}
174 204
175static ssize_t get_pwm_en(struct device *dev, char *buf, int nr) 205static ssize_t get_pwm_en(struct device *dev, struct device_attribute
206 *devattr, char *buf)
176{ 207{
208 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
177 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 209 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
178 return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr])); 210 return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[attr->index]));
179} 211}
180 212
181static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf) 213static ssize_t get_alarms(struct device *dev, struct device_attribute
214 *devattr, char *buf)
182{ 215{
183 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0); 216 struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
184 return sprintf(buf, "%d\n", data->alarms); 217 return sprintf(buf, "%d\n", data->alarms);
185} 218}
186 219
187static ssize_t set_fan_min(struct device *dev, const char *buf, 220static ssize_t set_fan_min(struct device *dev, struct device_attribute
188 size_t count, int nr) 221 *devattr, const char *buf, size_t count)
189{ 222{
190 struct i2c_client *client = to_i2c_client(dev); 223 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
191 struct smsc47m1_data *data = i2c_get_clientdata(client); 224 struct smsc47m1_data *data = dev_get_drvdata(dev);
225 int nr = attr->index;
192 long rpmdiv, val = simple_strtol(buf, NULL, 10); 226 long rpmdiv, val = simple_strtol(buf, NULL, 10);
193 227
194 mutex_lock(&data->update_lock); 228 mutex_lock(&data->update_lock);
@@ -200,7 +234,7 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
200 } 234 }
201 235
202 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv); 236 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
203 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), 237 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
204 data->fan_preload[nr]); 238 data->fan_preload[nr]);
205 mutex_unlock(&data->update_lock); 239 mutex_unlock(&data->update_lock);
206 240
@@ -211,12 +245,12 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
211 determined in part by the fan clock divider. This follows the principle 245 determined in part by the fan clock divider. This follows the principle
212 of least surprise; the user doesn't expect the fan minimum to change just 246 of least surprise; the user doesn't expect the fan minimum to change just
213 because the divider changed. */ 247 because the divider changed. */
214static ssize_t set_fan_div(struct device *dev, const char *buf, 248static ssize_t set_fan_div(struct device *dev, struct device_attribute
215 size_t count, int nr) 249 *devattr, const char *buf, size_t count)
216{ 250{
217 struct i2c_client *client = to_i2c_client(dev); 251 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
218 struct smsc47m1_data *data = i2c_get_clientdata(client); 252 struct smsc47m1_data *data = dev_get_drvdata(dev);
219 253 int nr = attr->index;
220 long new_div = simple_strtol(buf, NULL, 10), tmp; 254 long new_div = simple_strtol(buf, NULL, 10), tmp;
221 u8 old_div = DIV_FROM_REG(data->fan_div[nr]); 255 u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
222 256
@@ -234,27 +268,38 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
234 return -EINVAL; 268 return -EINVAL;
235 } 269 }
236 270
237 tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F; 271 switch (nr) {
238 tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6); 272 case 0:
239 smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp); 273 case 1:
274 tmp = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV)
275 & ~(0x03 << (4 + 2 * nr));
276 tmp |= data->fan_div[nr] << (4 + 2 * nr);
277 smsc47m1_write_value(data, SMSC47M1_REG_FANDIV, tmp);
278 break;
279 case 2:
280 tmp = smsc47m1_read_value(data, SMSC47M2_REG_FANDIV3) & 0xCF;
281 tmp |= data->fan_div[2] << 4;
282 smsc47m1_write_value(data, SMSC47M2_REG_FANDIV3, tmp);
283 break;
284 }
240 285
241 /* Preserve fan min */ 286 /* Preserve fan min */
242 tmp = 192 - (old_div * (192 - data->fan_preload[nr]) 287 tmp = 192 - (old_div * (192 - data->fan_preload[nr])
243 + new_div / 2) / new_div; 288 + new_div / 2) / new_div;
244 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191); 289 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
245 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), 290 smsc47m1_write_value(data, SMSC47M1_REG_FAN_PRELOAD[nr],
246 data->fan_preload[nr]); 291 data->fan_preload[nr]);
247 mutex_unlock(&data->update_lock); 292 mutex_unlock(&data->update_lock);
248 293
249 return count; 294 return count;
250} 295}
251 296
252static ssize_t set_pwm(struct device *dev, const char *buf, 297static ssize_t set_pwm(struct device *dev, struct device_attribute
253 size_t count, int nr) 298 *devattr, const char *buf, size_t count)
254{ 299{
255 struct i2c_client *client = to_i2c_client(dev); 300 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
256 struct smsc47m1_data *data = i2c_get_clientdata(client); 301 struct smsc47m1_data *data = dev_get_drvdata(dev);
257 302 int nr = attr->index;
258 long val = simple_strtol(buf, NULL, 10); 303 long val = simple_strtol(buf, NULL, 10);
259 304
260 if (val < 0 || val > 255) 305 if (val < 0 || val > 255)
@@ -263,19 +308,19 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
263 mutex_lock(&data->update_lock); 308 mutex_lock(&data->update_lock);
264 data->pwm[nr] &= 0x81; /* Preserve additional bits */ 309 data->pwm[nr] &= 0x81; /* Preserve additional bits */
265 data->pwm[nr] |= PWM_TO_REG(val); 310 data->pwm[nr] |= PWM_TO_REG(val);
266 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), 311 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
267 data->pwm[nr]); 312 data->pwm[nr]);
268 mutex_unlock(&data->update_lock); 313 mutex_unlock(&data->update_lock);
269 314
270 return count; 315 return count;
271} 316}
272 317
273static ssize_t set_pwm_en(struct device *dev, const char *buf, 318static ssize_t set_pwm_en(struct device *dev, struct device_attribute
274 size_t count, int nr) 319 *devattr, const char *buf, size_t count)
275{ 320{
276 struct i2c_client *client = to_i2c_client(dev); 321 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
277 struct smsc47m1_data *data = i2c_get_clientdata(client); 322 struct smsc47m1_data *data = dev_get_drvdata(dev);
278 323 int nr = attr->index;
279 long val = simple_strtol(buf, NULL, 10); 324 long val = simple_strtol(buf, NULL, 10);
280 325
281 if (val != 0 && val != 1) 326 if (val != 0 && val != 1)
@@ -284,7 +329,7 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
284 mutex_lock(&data->update_lock); 329 mutex_lock(&data->update_lock);
285 data->pwm[nr] &= 0xFE; /* preserve the other bits */ 330 data->pwm[nr] &= 0xFE; /* preserve the other bits */
286 data->pwm[nr] |= !val; 331 data->pwm[nr] |= !val;
287 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), 332 smsc47m1_write_value(data, SMSC47M1_REG_PWM[nr],
288 data->pwm[nr]); 333 data->pwm[nr]);
289 mutex_unlock(&data->update_lock); 334 mutex_unlock(&data->update_lock);
290 335
@@ -292,79 +337,55 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
292} 337}
293 338
294#define fan_present(offset) \ 339#define fan_present(offset) \
295static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf) \ 340static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan, \
296{ \ 341 NULL, offset - 1); \
297 return get_fan(dev, buf, offset - 1); \ 342static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
298} \ 343 get_fan_min, set_fan_min, offset - 1); \
299static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf) \ 344static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
300{ \ 345 get_fan_div, set_fan_div, offset - 1); \
301 return get_fan_min(dev, buf, offset - 1); \ 346static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
302} \ 347 get_pwm, set_pwm, offset - 1); \
303static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr, \ 348static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
304 const char *buf, size_t count) \ 349 get_pwm_en, set_pwm_en, offset - 1)
305{ \
306 return set_fan_min(dev, buf, count, offset - 1); \
307} \
308static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf) \
309{ \
310 return get_fan_div(dev, buf, offset - 1); \
311} \
312static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr, \
313 const char *buf, size_t count) \
314{ \
315 return set_fan_div(dev, buf, count, offset - 1); \
316} \
317static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf) \
318{ \
319 return get_pwm(dev, buf, offset - 1); \
320} \
321static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr, \
322 const char *buf, size_t count) \
323{ \
324 return set_pwm(dev, buf, count, offset - 1); \
325} \
326static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf) \
327{ \
328 return get_pwm_en(dev, buf, offset - 1); \
329} \
330static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr, \
331 const char *buf, size_t count) \
332{ \
333 return set_pwm_en(dev, buf, count, offset - 1); \
334} \
335static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset, \
336 NULL); \
337static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
338 get_fan##offset##_min, set_fan##offset##_min); \
339static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
340 get_fan##offset##_div, set_fan##offset##_div); \
341static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
342 get_pwm##offset, set_pwm##offset); \
343static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
344 get_pwm##offset##_en, set_pwm##offset##_en);
345 350
346fan_present(1); 351fan_present(1);
347fan_present(2); 352fan_present(2);
353fan_present(3);
348 354
349static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL); 355static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
350 356
357static ssize_t show_name(struct device *dev, struct device_attribute
358 *devattr, char *buf)
359{
360 struct smsc47m1_data *data = dev_get_drvdata(dev);
361
362 return sprintf(buf, "%s\n", data->name);
363}
364static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
365
351/* Almost all sysfs files may or may not be created depending on the chip 366/* Almost all sysfs files may or may not be created depending on the chip
352 setup so we create them individually. It is still convenient to define a 367 setup so we create them individually. It is still convenient to define a
353 group to remove them all at once. */ 368 group to remove them all at once. */
354static struct attribute *smsc47m1_attributes[] = { 369static struct attribute *smsc47m1_attributes[] = {
355 &dev_attr_fan1_input.attr, 370 &sensor_dev_attr_fan1_input.dev_attr.attr,
356 &dev_attr_fan1_min.attr, 371 &sensor_dev_attr_fan1_min.dev_attr.attr,
357 &dev_attr_fan1_div.attr, 372 &sensor_dev_attr_fan1_div.dev_attr.attr,
358 &dev_attr_fan2_input.attr, 373 &sensor_dev_attr_fan2_input.dev_attr.attr,
359 &dev_attr_fan2_min.attr, 374 &sensor_dev_attr_fan2_min.dev_attr.attr,
360 &dev_attr_fan2_div.attr, 375 &sensor_dev_attr_fan2_div.dev_attr.attr,
361 376 &sensor_dev_attr_fan3_input.dev_attr.attr,
362 &dev_attr_pwm1.attr, 377 &sensor_dev_attr_fan3_min.dev_attr.attr,
363 &dev_attr_pwm1_enable.attr, 378 &sensor_dev_attr_fan3_div.dev_attr.attr,
364 &dev_attr_pwm2.attr, 379
365 &dev_attr_pwm2_enable.attr, 380 &sensor_dev_attr_pwm1.dev_attr.attr,
381 &sensor_dev_attr_pwm1_enable.dev_attr.attr,
382 &sensor_dev_attr_pwm2.dev_attr.attr,
383 &sensor_dev_attr_pwm2_enable.dev_attr.attr,
384 &sensor_dev_attr_pwm3.dev_attr.attr,
385 &sensor_dev_attr_pwm3_enable.dev_attr.attr,
366 386
367 &dev_attr_alarms.attr, 387 &dev_attr_alarms.attr,
388 &dev_attr_name.attr,
368 NULL 389 NULL
369}; 390};
370 391
@@ -372,7 +393,8 @@ static const struct attribute_group smsc47m1_group = {
372 .attrs = smsc47m1_attributes, 393 .attrs = smsc47m1_attributes,
373}; 394};
374 395
375static int __init smsc47m1_find(unsigned short *addr) 396static int __init smsc47m1_find(unsigned short *addr,
397 struct smsc47m1_sio_data *sio_data)
376{ 398{
377 u8 val; 399 u8 val;
378 400
@@ -386,18 +408,32 @@ static int __init smsc47m1_find(unsigned short *addr)
386 * can do much more besides (device id 0x60). 408 * can do much more besides (device id 0x60).
387 * The LPC47M997 is undocumented, but seems to be compatible with 409 * The LPC47M997 is undocumented, but seems to be compatible with
388 * the LPC47M192, and has the same device id. 410 * the LPC47M192, and has the same device id.
411 * The LPC47M292 (device id 0x6B) is somewhat compatible, but it
412 * supports a 3rd fan, and the pin configuration registers are
413 * unfortunately different.
389 */ 414 */
390 if (val == 0x51) 415 switch (val) {
391 printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n"); 416 case 0x51:
392 else if (val == 0x59) 417 pr_info(DRVNAME ": Found SMSC LPC47B27x\n");
393 printk(KERN_INFO "smsc47m1: Found SMSC " 418 sio_data->type = smsc47m1;
394 "LPC47M10x/LPC47M112/LPC47M13x\n"); 419 break;
395 else if (val == 0x5F) 420 case 0x59:
396 printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n"); 421 pr_info(DRVNAME ": Found SMSC LPC47M10x/LPC47M112/LPC47M13x\n");
397 else if (val == 0x60) 422 sio_data->type = smsc47m1;
398 printk(KERN_INFO "smsc47m1: Found SMSC " 423 break;
399 "LPC47M15x/LPC47M192/LPC47M997\n"); 424 case 0x5F:
400 else { 425 pr_info(DRVNAME ": Found SMSC LPC47M14x\n");
426 sio_data->type = smsc47m1;
427 break;
428 case 0x60:
429 pr_info(DRVNAME ": Found SMSC LPC47M15x/LPC47M192/LPC47M997\n");
430 sio_data->type = smsc47m1;
431 break;
432 case 0x6B:
433 pr_info(DRVNAME ": Found SMSC LPC47M292\n");
434 sio_data->type = smsc47m2;
435 break;
436 default:
401 superio_exit(); 437 superio_exit();
402 return -ENODEV; 438 return -ENODEV;
403 } 439 }
@@ -407,7 +443,7 @@ static int __init smsc47m1_find(unsigned short *addr)
407 | superio_inb(SUPERIO_REG_BASE + 1); 443 | superio_inb(SUPERIO_REG_BASE + 1);
408 val = superio_inb(SUPERIO_REG_ACT); 444 val = superio_inb(SUPERIO_REG_ACT);
409 if (*addr == 0 || (val & 0x01) == 0) { 445 if (*addr == 0 || (val & 0x01) == 0) {
410 printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n"); 446 pr_info(DRVNAME ": Device is disabled, will not use\n");
411 superio_exit(); 447 superio_exit();
412 return -ENODEV; 448 return -ENODEV;
413 } 449 }
@@ -416,15 +452,25 @@ static int __init smsc47m1_find(unsigned short *addr)
416 return 0; 452 return 0;
417} 453}
418 454
419static int smsc47m1_detect(struct i2c_adapter *adapter) 455static int __devinit smsc47m1_probe(struct platform_device *pdev)
420{ 456{
421 struct i2c_client *new_client; 457 struct device *dev = &pdev->dev;
458 struct smsc47m1_sio_data *sio_data = dev->platform_data;
422 struct smsc47m1_data *data; 459 struct smsc47m1_data *data;
460 struct resource *res;
423 int err = 0; 461 int err = 0;
424 int fan1, fan2, pwm1, pwm2; 462 int fan1, fan2, fan3, pwm1, pwm2, pwm3;
425 463
426 if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.driver.name)) { 464 static const char *names[] = {
427 dev_err(&adapter->dev, "Region 0x%x already in use!\n", address); 465 "smsc47m1",
466 "smsc47m2",
467 };
468
469 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
470 if (!request_region(res->start, SMSC_EXTENT, DRVNAME)) {
471 dev_err(dev, "Region 0x%lx-0x%lx already in use!\n",
472 (unsigned long)res->start,
473 (unsigned long)res->end);
428 return -EBUSY; 474 return -EBUSY;
429 } 475 }
430 476
@@ -433,93 +479,114 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
433 goto error_release; 479 goto error_release;
434 } 480 }
435 481
436 new_client = &data->client; 482 data->addr = res->start;
437 i2c_set_clientdata(new_client, data); 483 data->type = sio_data->type;
438 new_client->addr = address; 484 data->name = names[sio_data->type];
439 mutex_init(&data->lock);
440 new_client->adapter = adapter;
441 new_client->driver = &smsc47m1_driver;
442 new_client->flags = 0;
443
444 strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
445 mutex_init(&data->update_lock); 485 mutex_init(&data->update_lock);
486 platform_set_drvdata(pdev, data);
446 487
447 /* If no function is properly configured, there's no point in 488 /* If no function is properly configured, there's no point in
448 actually registering the chip. */ 489 actually registering the chip. */
449 fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05) 490 pwm1 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(0)) & 0x05)
450 == 0x05;
451 fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05)
452 == 0x05;
453 pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
454 == 0x04; 491 == 0x04;
455 pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05) 492 pwm2 = (smsc47m1_read_value(data, SMSC47M1_REG_PPIN(1)) & 0x05)
456 == 0x04; 493 == 0x04;
457 if (!(fan1 || fan2 || pwm1 || pwm2)) { 494 if (data->type == smsc47m2) {
458 dev_warn(&adapter->dev, "Device at 0x%x is not configured, " 495 fan1 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN1)
459 "will not use\n", new_client->addr); 496 & 0x0d) == 0x09;
497 fan2 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN2)
498 & 0x0d) == 0x09;
499 fan3 = (smsc47m1_read_value(data, SMSC47M2_REG_TPIN3)
500 & 0x0d) == 0x0d;
501 pwm3 = (smsc47m1_read_value(data, SMSC47M2_REG_PPIN3)
502 & 0x0d) == 0x08;
503 } else {
504 fan1 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(0))
505 & 0x05) == 0x05;
506 fan2 = (smsc47m1_read_value(data, SMSC47M1_REG_TPIN(1))
507 & 0x05) == 0x05;
508 fan3 = 0;
509 pwm3 = 0;
510 }
511 if (!(fan1 || fan2 || fan3 || pwm1 || pwm2 || pwm3)) {
512 dev_warn(dev, "Device not configured, will not use\n");
460 err = -ENODEV; 513 err = -ENODEV;
461 goto error_free; 514 goto error_free;
462 } 515 }
463 516
464 if ((err = i2c_attach_client(new_client)))
465 goto error_free;
466
467 /* Some values (fan min, clock dividers, pwm registers) may be 517 /* Some values (fan min, clock dividers, pwm registers) may be
468 needed before any update is triggered, so we better read them 518 needed before any update is triggered, so we better read them
469 at least once here. We don't usually do it that way, but in 519 at least once here. We don't usually do it that way, but in
470 this particular case, manually reading 5 registers out of 8 520 this particular case, manually reading 5 registers out of 8
471 doesn't make much sense and we're better using the existing 521 doesn't make much sense and we're better using the existing
472 function. */ 522 function. */
473 smsc47m1_update_device(&new_client->dev, 1); 523 smsc47m1_update_device(dev, 1);
474 524
475 /* Register sysfs hooks */ 525 /* Register sysfs hooks */
476 if (fan1) { 526 if (fan1) {
477 if ((err = device_create_file(&new_client->dev, 527 if ((err = device_create_file(dev,
478 &dev_attr_fan1_input)) 528 &sensor_dev_attr_fan1_input.dev_attr))
479 || (err = device_create_file(&new_client->dev, 529 || (err = device_create_file(dev,
480 &dev_attr_fan1_min)) 530 &sensor_dev_attr_fan1_min.dev_attr))
481 || (err = device_create_file(&new_client->dev, 531 || (err = device_create_file(dev,
482 &dev_attr_fan1_div))) 532 &sensor_dev_attr_fan1_div.dev_attr)))
483 goto error_remove_files; 533 goto error_remove_files;
484 } else 534 } else
485 dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, " 535 dev_dbg(dev, "Fan 1 not enabled by hardware, skipping\n");
486 "skipping\n");
487 536
488 if (fan2) { 537 if (fan2) {
489 if ((err = device_create_file(&new_client->dev, 538 if ((err = device_create_file(dev,
490 &dev_attr_fan2_input)) 539 &sensor_dev_attr_fan2_input.dev_attr))
491 || (err = device_create_file(&new_client->dev, 540 || (err = device_create_file(dev,
492 &dev_attr_fan2_min)) 541 &sensor_dev_attr_fan2_min.dev_attr))
493 || (err = device_create_file(&new_client->dev, 542 || (err = device_create_file(dev,
494 &dev_attr_fan2_div))) 543 &sensor_dev_attr_fan2_div.dev_attr)))
495 goto error_remove_files; 544 goto error_remove_files;
496 } else 545 } else
497 dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, " 546 dev_dbg(dev, "Fan 2 not enabled by hardware, skipping\n");
498 "skipping\n"); 547
548 if (fan3) {
549 if ((err = device_create_file(dev,
550 &sensor_dev_attr_fan3_input.dev_attr))
551 || (err = device_create_file(dev,
552 &sensor_dev_attr_fan3_min.dev_attr))
553 || (err = device_create_file(dev,
554 &sensor_dev_attr_fan3_div.dev_attr)))
555 goto error_remove_files;
556 } else
557 dev_dbg(dev, "Fan 3 not enabled by hardware, skipping\n");
499 558
500 if (pwm1) { 559 if (pwm1) {
501 if ((err = device_create_file(&new_client->dev, 560 if ((err = device_create_file(dev,
502 &dev_attr_pwm1)) 561 &sensor_dev_attr_pwm1.dev_attr))
503 || (err = device_create_file(&new_client->dev, 562 || (err = device_create_file(dev,
504 &dev_attr_pwm1_enable))) 563 &sensor_dev_attr_pwm1_enable.dev_attr)))
505 goto error_remove_files; 564 goto error_remove_files;
506 } else 565 } else
507 dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, " 566 dev_dbg(dev, "PWM 1 not enabled by hardware, skipping\n");
508 "skipping\n"); 567
509 if (pwm2) { 568 if (pwm2) {
510 if ((err = device_create_file(&new_client->dev, 569 if ((err = device_create_file(dev,
511 &dev_attr_pwm2)) 570 &sensor_dev_attr_pwm2.dev_attr))
512 || (err = device_create_file(&new_client->dev, 571 || (err = device_create_file(dev,
513 &dev_attr_pwm2_enable))) 572 &sensor_dev_attr_pwm2_enable.dev_attr)))
573 goto error_remove_files;
574 } else
575 dev_dbg(dev, "PWM 2 not enabled by hardware, skipping\n");
576
577 if (pwm3) {
578 if ((err = device_create_file(dev,
579 &sensor_dev_attr_pwm3.dev_attr))
580 || (err = device_create_file(dev,
581 &sensor_dev_attr_pwm3_enable.dev_attr)))
514 goto error_remove_files; 582 goto error_remove_files;
515 } else 583 } else
516 dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, " 584 dev_dbg(dev, "PWM 3 not enabled by hardware, skipping\n");
517 "skipping\n");
518 585
519 if ((err = device_create_file(&new_client->dev, &dev_attr_alarms))) 586 if ((err = device_create_file(dev, &dev_attr_alarms)))
520 goto error_remove_files; 587 goto error_remove_files;
521 588
522 data->class_dev = hwmon_device_register(&new_client->dev); 589 data->class_dev = hwmon_device_register(dev);
523 if (IS_ERR(data->class_dev)) { 590 if (IS_ERR(data->class_dev)) {
524 err = PTR_ERR(data->class_dev); 591 err = PTR_ERR(data->class_dev);
525 goto error_remove_files; 592 goto error_remove_files;
@@ -528,78 +595,71 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
528 return 0; 595 return 0;
529 596
530error_remove_files: 597error_remove_files:
531 sysfs_remove_group(&new_client->dev.kobj, &smsc47m1_group); 598 sysfs_remove_group(&dev->kobj, &smsc47m1_group);
532 i2c_detach_client(new_client);
533error_free: 599error_free:
534 kfree(data); 600 kfree(data);
535error_release: 601error_release:
536 release_region(address, SMSC_EXTENT); 602 release_region(res->start, SMSC_EXTENT);
537 return err; 603 return err;
538} 604}
539 605
540static int smsc47m1_detach_client(struct i2c_client *client) 606static int __devexit smsc47m1_remove(struct platform_device *pdev)
541{ 607{
542 struct smsc47m1_data *data = i2c_get_clientdata(client); 608 struct smsc47m1_data *data = platform_get_drvdata(pdev);
543 int err; 609 struct resource *res;
544 610
611 platform_set_drvdata(pdev, NULL);
545 hwmon_device_unregister(data->class_dev); 612 hwmon_device_unregister(data->class_dev);
546 sysfs_remove_group(&client->dev.kobj, &smsc47m1_group); 613 sysfs_remove_group(&pdev->dev.kobj, &smsc47m1_group);
547
548 if ((err = i2c_detach_client(client)))
549 return err;
550 614
551 release_region(client->addr, SMSC_EXTENT); 615 res = platform_get_resource(pdev, IORESOURCE_IO, 0);
616 release_region(res->start, SMSC_EXTENT);
552 kfree(data); 617 kfree(data);
553 618
554 return 0; 619 return 0;
555} 620}
556 621
557static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
558{
559 int res;
560
561 mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
562 res = inb_p(client->addr + reg);
563 mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
564 return res;
565}
566
567static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
568{
569 mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
570 outb_p(value, client->addr + reg);
571 mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
572}
573
574static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 622static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
575 int init) 623 int init)
576{ 624{
577 struct i2c_client *client = to_i2c_client(dev); 625 struct smsc47m1_data *data = dev_get_drvdata(dev);
578 struct smsc47m1_data *data = i2c_get_clientdata(client);
579 626
580 mutex_lock(&data->update_lock); 627 mutex_lock(&data->update_lock);
581 628
582 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { 629 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
583 int i; 630 int i, fan_nr;
584 631 fan_nr = data->type == smsc47m2 ? 3 : 2;
585 for (i = 0; i < 2; i++) { 632
586 data->fan[i] = smsc47m1_read_value(client, 633 for (i = 0; i < fan_nr; i++) {
587 SMSC47M1_REG_FAN(i)); 634 data->fan[i] = smsc47m1_read_value(data,
588 data->fan_preload[i] = smsc47m1_read_value(client, 635 SMSC47M1_REG_FAN[i]);
589 SMSC47M1_REG_FAN_PRELOAD(i)); 636 data->fan_preload[i] = smsc47m1_read_value(data,
590 data->pwm[i] = smsc47m1_read_value(client, 637 SMSC47M1_REG_FAN_PRELOAD[i]);
591 SMSC47M1_REG_PWM(i)); 638 data->pwm[i] = smsc47m1_read_value(data,
639 SMSC47M1_REG_PWM[i]);
592 } 640 }
593 641
594 i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV); 642 i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
595 data->fan_div[0] = (i >> 4) & 0x03; 643 data->fan_div[0] = (i >> 4) & 0x03;
596 data->fan_div[1] = i >> 6; 644 data->fan_div[1] = i >> 6;
597 645
598 data->alarms = smsc47m1_read_value(client, 646 data->alarms = smsc47m1_read_value(data,
599 SMSC47M1_REG_ALARM) >> 6; 647 SMSC47M1_REG_ALARM) >> 6;
600 /* Clear alarms if needed */ 648 /* Clear alarms if needed */
601 if (data->alarms) 649 if (data->alarms)
602 smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0); 650 smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
651
652 if (fan_nr >= 3) {
653 data->fan_div[2] = (smsc47m1_read_value(data,
654 SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
655 data->alarms |= (smsc47m1_read_value(data,
656 SMSC47M2_REG_ALARM6) & 0x40) >> 4;
657 /* Clear alarm if needed */
658 if (data->alarms & 0x04)
659 smsc47m1_write_value(data,
660 SMSC47M2_REG_ALARM6,
661 0x40);
662 }
603 663
604 data->last_updated = jiffies; 664 data->last_updated = jiffies;
605 } 665 }
@@ -608,18 +668,86 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
608 return data; 668 return data;
609} 669}
610 670
671static int __init smsc47m1_device_add(unsigned short address,
672 const struct smsc47m1_sio_data *sio_data)
673{
674 struct resource res = {
675 .start = address,
676 .end = address + SMSC_EXTENT - 1,
677 .name = DRVNAME,
678 .flags = IORESOURCE_IO,
679 };
680 int err;
681
682 pdev = platform_device_alloc(DRVNAME, address);
683 if (!pdev) {
684 err = -ENOMEM;
685 printk(KERN_ERR DRVNAME ": Device allocation failed\n");
686 goto exit;
687 }
688
689 err = platform_device_add_resources(pdev, &res, 1);
690 if (err) {
691 printk(KERN_ERR DRVNAME ": Device resource addition failed "
692 "(%d)\n", err);
693 goto exit_device_put;
694 }
695
696 pdev->dev.platform_data = kmalloc(sizeof(struct smsc47m1_sio_data),
697 GFP_KERNEL);
698 if (!pdev->dev.platform_data) {
699 err = -ENOMEM;
700 printk(KERN_ERR DRVNAME ": Platform data allocation failed\n");
701 goto exit_device_put;
702 }
703 memcpy(pdev->dev.platform_data, sio_data,
704 sizeof(struct smsc47m1_sio_data));
705
706 err = platform_device_add(pdev);
707 if (err) {
708 printk(KERN_ERR DRVNAME ": Device addition failed (%d)\n",
709 err);
710 goto exit_device_put;
711 }
712
713 return 0;
714
715exit_device_put:
716 platform_device_put(pdev);
717exit:
718 return err;
719}
720
611static int __init sm_smsc47m1_init(void) 721static int __init sm_smsc47m1_init(void)
612{ 722{
613 if (smsc47m1_find(&address)) { 723 int err;
724 unsigned short address;
725 struct smsc47m1_sio_data sio_data;
726
727 if (smsc47m1_find(&address, &sio_data))
614 return -ENODEV; 728 return -ENODEV;
615 }
616 729
617 return i2c_isa_add_driver(&smsc47m1_driver); 730 err = platform_driver_register(&smsc47m1_driver);
731 if (err)
732 goto exit;
733
734 /* Sets global pdev as a side effect */
735 err = smsc47m1_device_add(address, &sio_data);
736 if (err)
737 goto exit_driver;
738
739 return 0;
740
741exit_driver:
742 platform_driver_unregister(&smsc47m1_driver);
743exit:
744 return err;
618} 745}
619 746
620static void __exit sm_smsc47m1_exit(void) 747static void __exit sm_smsc47m1_exit(void)
621{ 748{
622 i2c_isa_del_driver(&smsc47m1_driver); 749 platform_device_unregister(pdev);
750 platform_driver_unregister(&smsc47m1_driver);
623} 751}
624 752
625MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>"); 753MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");