Merge rsync://oss.sgi.com/git/xfs-2.6
[linux-2.6] / drivers / i2c / chips / smsc47m1.c
1 /*
2     smsc47m1.c - Part of lm_sensors, Linux kernel modules
3                  for hardware monitoring
4
5     Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x and LPC47M14x
6     Super-I/O chips.
7
8     Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
9     Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
10     Ported to Linux 2.6 by Gabriele Gorla <gorlik@yahoo.com>
11                         and Jean Delvare
12
13     This program is free software; you can redistribute it and/or modify
14     it under the terms of the GNU General Public License as published by
15     the Free Software Foundation; either version 2 of the License, or
16     (at your option) any later version.
17
18     This program is distributed in the hope that it will be useful,
19     but WITHOUT ANY WARRANTY; without even the implied warranty of
20     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21     GNU General Public License for more details.
22
23     You should have received a copy of the GNU General Public License
24     along with this program; if not, write to the Free Software
25     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 */
27
28 #include <linux/module.h>
29 #include <linux/slab.h>
30 #include <linux/ioport.h>
31 #include <linux/jiffies.h>
32 #include <linux/i2c.h>
33 #include <linux/i2c-sensor.h>
34 #include <linux/init.h>
35 #include <asm/io.h>
36
37 static unsigned short normal_i2c[] = { I2C_CLIENT_END };
38 /* Address is autodetected, there is no default value */
39 static unsigned int normal_isa[] = { 0x0000, I2C_CLIENT_ISA_END };
40 static struct i2c_force_data forces[] = {{NULL}};
41
42 enum chips { any_chip, smsc47m1 };
43 static struct i2c_address_data addr_data = {
44         .normal_i2c             = normal_i2c,
45         .normal_isa             = normal_isa,
46         .forces                 = forces,
47 };
48
49 /* Super-I/0 registers and commands */
50
51 #define REG     0x2e    /* The register to read/write */
52 #define VAL     0x2f    /* The value to read/write */
53
54 static inline void
55 superio_outb(int reg, int val)
56 {
57         outb(reg, REG);
58         outb(val, VAL);
59 }
60
61 static inline int
62 superio_inb(int reg)
63 {
64         outb(reg, REG);
65         return inb(VAL);
66 }
67
68 /* logical device for fans is 0x0A */
69 #define superio_select() superio_outb(0x07, 0x0A)
70
71 static inline void
72 superio_enter(void)
73 {
74         outb(0x55, REG);
75 }
76
77 static inline void
78 superio_exit(void)
79 {
80         outb(0xAA, REG);
81 }
82
83 #define SUPERIO_REG_ACT         0x30
84 #define SUPERIO_REG_BASE        0x60
85 #define SUPERIO_REG_DEVID       0x20
86
87 /* Logical device registers */
88
89 #define SMSC_EXTENT             0x80
90
91 /* nr is 0 or 1 in the macros below */
92 #define SMSC47M1_REG_ALARM              0x04
93 #define SMSC47M1_REG_TPIN(nr)           (0x34 - (nr))
94 #define SMSC47M1_REG_PPIN(nr)           (0x36 - (nr))
95 #define SMSC47M1_REG_PWM(nr)            (0x56 + (nr))
96 #define SMSC47M1_REG_FANDIV             0x58
97 #define SMSC47M1_REG_FAN(nr)            (0x59 + (nr))
98 #define SMSC47M1_REG_FAN_PRELOAD(nr)    (0x5B + (nr))
99
100 #define MIN_FROM_REG(reg,div)           ((reg)>=192 ? 0 : \
101                                          983040/((192-(reg))*(div)))
102 #define FAN_FROM_REG(reg,div,preload)   ((reg)<=(preload) || (reg)==255 ? 0 : \
103                                          983040/(((reg)-(preload))*(div)))
104 #define DIV_FROM_REG(reg)               (1 << (reg))
105 #define PWM_FROM_REG(reg)               (((reg) & 0x7E) << 1)
106 #define PWM_EN_FROM_REG(reg)            ((~(reg)) & 0x01)
107 #define PWM_TO_REG(reg)                 (((reg) >> 1) & 0x7E)
108
109 struct smsc47m1_data {
110         struct i2c_client client;
111         struct semaphore lock;
112
113         struct semaphore update_lock;
114         unsigned long last_updated;     /* In jiffies */
115
116         u8 fan[2];              /* Register value */
117         u8 fan_preload[2];      /* Register value */
118         u8 fan_div[2];          /* Register encoding, shifted right */
119         u8 alarms;              /* Register encoding */
120         u8 pwm[2];              /* Register value (bit 7 is enable) */
121 };
122
123
124 static int smsc47m1_attach_adapter(struct i2c_adapter *adapter);
125 static int smsc47m1_find(int *address);
126 static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind);
127 static int smsc47m1_detach_client(struct i2c_client *client);
128
129 static int smsc47m1_read_value(struct i2c_client *client, u8 reg);
130 static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value);
131
132 static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
133                 int init);
134
135
136 static struct i2c_driver smsc47m1_driver = {
137         .owner          = THIS_MODULE,
138         .name           = "smsc47m1",
139         .id             = I2C_DRIVERID_SMSC47M1,
140         .flags          = I2C_DF_NOTIFY,
141         .attach_adapter = smsc47m1_attach_adapter,
142         .detach_client  = smsc47m1_detach_client,
143 };
144
145 /* nr is 0 or 1 in the callback functions below */
146
147 static ssize_t get_fan(struct device *dev, char *buf, int nr)
148 {
149         struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
150         /* This chip (stupidly) stops monitoring fan speed if PWM is
151            enabled and duty cycle is 0%. This is fine if the monitoring
152            and control concern the same fan, but troublesome if they are
153            not (which could as well happen). */
154         int rpm = (data->pwm[nr] & 0x7F) == 0x00 ? 0 :
155                   FAN_FROM_REG(data->fan[nr],
156                                DIV_FROM_REG(data->fan_div[nr]),
157                                data->fan_preload[nr]);
158         return sprintf(buf, "%d\n", rpm);
159 }
160
161 static ssize_t get_fan_min(struct device *dev, char *buf, int nr)
162 {
163         struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
164         int rpm = MIN_FROM_REG(data->fan_preload[nr],
165                                DIV_FROM_REG(data->fan_div[nr]));
166         return sprintf(buf, "%d\n", rpm);
167 }
168
169 static ssize_t get_fan_div(struct device *dev, char *buf, int nr)
170 {
171         struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
172         return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]));
173 }
174
175 static ssize_t get_pwm(struct device *dev, char *buf, int nr)
176 {
177         struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
178         return sprintf(buf, "%d\n", PWM_FROM_REG(data->pwm[nr]));
179 }
180
181 static ssize_t get_pwm_en(struct device *dev, char *buf, int nr)
182 {
183         struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
184         return sprintf(buf, "%d\n", PWM_EN_FROM_REG(data->pwm[nr]));
185 }
186
187 static ssize_t get_alarms(struct device *dev, struct device_attribute *attr, char *buf)
188 {
189         struct smsc47m1_data *data = smsc47m1_update_device(dev, 0);
190         return sprintf(buf, "%d\n", data->alarms);
191 }
192
193 static ssize_t set_fan_min(struct device *dev, const char *buf,
194                 size_t count, int nr)
195 {
196         struct i2c_client *client = to_i2c_client(dev);
197         struct smsc47m1_data *data = i2c_get_clientdata(client);
198         long rpmdiv, val = simple_strtol(buf, NULL, 10);
199
200         down(&data->update_lock);
201         rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
202
203         if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
204                 up(&data->update_lock);
205                 return -EINVAL;
206         }
207
208         data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
209         smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
210                              data->fan_preload[nr]);
211         up(&data->update_lock);
212
213         return count;
214 }
215
216 /* Note: we save and restore the fan minimum here, because its value is
217    determined in part by the fan clock divider.  This follows the principle
218    of least suprise; the user doesn't expect the fan minimum to change just
219    because the divider changed. */
220 static ssize_t set_fan_div(struct device *dev, const char *buf,
221                 size_t count, int nr)
222 {
223         struct i2c_client *client = to_i2c_client(dev);
224         struct smsc47m1_data *data = i2c_get_clientdata(client);
225
226         long new_div = simple_strtol(buf, NULL, 10), tmp;
227         u8 old_div = DIV_FROM_REG(data->fan_div[nr]);
228
229         if (new_div == old_div) /* No change */
230                 return count;
231
232         down(&data->update_lock);
233         switch (new_div) {
234         case 1: data->fan_div[nr] = 0; break;
235         case 2: data->fan_div[nr] = 1; break;
236         case 4: data->fan_div[nr] = 2; break;
237         case 8: data->fan_div[nr] = 3; break;
238         default:
239                 up(&data->update_lock);
240                 return -EINVAL;
241         }
242
243         tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
244         tmp |= (data->fan_div[0] << 4) | (data->fan_div[1] << 6);
245         smsc47m1_write_value(client, SMSC47M1_REG_FANDIV, tmp);
246
247         /* Preserve fan min */
248         tmp = 192 - (old_div * (192 - data->fan_preload[nr])
249                      + new_div / 2) / new_div;
250         data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
251         smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
252                              data->fan_preload[nr]);
253         up(&data->update_lock);
254
255         return count;
256 }
257
258 static ssize_t set_pwm(struct device *dev, const char *buf,
259                 size_t count, int nr)
260 {
261         struct i2c_client *client = to_i2c_client(dev);
262         struct smsc47m1_data *data = i2c_get_clientdata(client);
263
264         long val = simple_strtol(buf, NULL, 10);
265
266         if (val < 0 || val > 255)
267                 return -EINVAL;
268
269         down(&data->update_lock);
270         data->pwm[nr] &= 0x81; /* Preserve additional bits */
271         data->pwm[nr] |= PWM_TO_REG(val);
272         smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
273                              data->pwm[nr]);
274         up(&data->update_lock);
275
276         return count;
277 }
278
279 static ssize_t set_pwm_en(struct device *dev, const char *buf,
280                 size_t count, int nr)
281 {
282         struct i2c_client *client = to_i2c_client(dev);
283         struct smsc47m1_data *data = i2c_get_clientdata(client);
284
285         long val = simple_strtol(buf, NULL, 10);
286         
287         if (val != 0 && val != 1)
288                 return -EINVAL;
289
290         down(&data->update_lock);
291         data->pwm[nr] &= 0xFE; /* preserve the other bits */
292         data->pwm[nr] |= !val;
293         smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
294                              data->pwm[nr]);
295         up(&data->update_lock);
296
297         return count;
298 }
299
300 #define fan_present(offset)                                             \
301 static ssize_t get_fan##offset (struct device *dev, struct device_attribute *attr, char *buf)           \
302 {                                                                       \
303         return get_fan(dev, buf, offset - 1);                           \
304 }                                                                       \
305 static ssize_t get_fan##offset##_min (struct device *dev, struct device_attribute *attr, char *buf)     \
306 {                                                                       \
307         return get_fan_min(dev, buf, offset - 1);                       \
308 }                                                                       \
309 static ssize_t set_fan##offset##_min (struct device *dev, struct device_attribute *attr,                \
310                 const char *buf, size_t count)                          \
311 {                                                                       \
312         return set_fan_min(dev, buf, count, offset - 1);                \
313 }                                                                       \
314 static ssize_t get_fan##offset##_div (struct device *dev, struct device_attribute *attr, char *buf)     \
315 {                                                                       \
316         return get_fan_div(dev, buf, offset - 1);                       \
317 }                                                                       \
318 static ssize_t set_fan##offset##_div (struct device *dev, struct device_attribute *attr,                \
319                 const char *buf, size_t count)                          \
320 {                                                                       \
321         return set_fan_div(dev, buf, count, offset - 1);                \
322 }                                                                       \
323 static ssize_t get_pwm##offset (struct device *dev, struct device_attribute *attr, char *buf)           \
324 {                                                                       \
325         return get_pwm(dev, buf, offset - 1);                           \
326 }                                                                       \
327 static ssize_t set_pwm##offset (struct device *dev, struct device_attribute *attr,                      \
328                 const char *buf, size_t count)                          \
329 {                                                                       \
330         return set_pwm(dev, buf, count, offset - 1);                    \
331 }                                                                       \
332 static ssize_t get_pwm##offset##_en (struct device *dev, struct device_attribute *attr, char *buf)      \
333 {                                                                       \
334         return get_pwm_en(dev, buf, offset - 1);                        \
335 }                                                                       \
336 static ssize_t set_pwm##offset##_en (struct device *dev, struct device_attribute *attr,         \
337                 const char *buf, size_t count)                          \
338 {                                                                       \
339         return set_pwm_en(dev, buf, count, offset - 1);                 \
340 }                                                                       \
341 static DEVICE_ATTR(fan##offset##_input, S_IRUGO, get_fan##offset,       \
342                 NULL);                                                  \
343 static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR,                \
344                 get_fan##offset##_min, set_fan##offset##_min);          \
345 static DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR,                \
346                 get_fan##offset##_div, set_fan##offset##_div);          \
347 static DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR,                      \
348                 get_pwm##offset, set_pwm##offset);                      \
349 static DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR,             \
350                 get_pwm##offset##_en, set_pwm##offset##_en);
351
352 fan_present(1);
353 fan_present(2);
354
355 static DEVICE_ATTR(alarms, S_IRUGO, get_alarms, NULL);
356
357 static int smsc47m1_attach_adapter(struct i2c_adapter *adapter)
358 {
359         if (!(adapter->class & I2C_CLASS_HWMON))
360                 return 0;
361         return i2c_detect(adapter, &addr_data, smsc47m1_detect);
362 }
363
364 static int smsc47m1_find(int *address)
365 {
366         u8 val;
367
368         superio_enter();
369         val = superio_inb(SUPERIO_REG_DEVID);
370
371         /*
372          * SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
373          * 0x5F) and LPC47B27x (device id 0x51) have fan control.
374          * The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
375          * can do much more besides (device id 0x60, unsupported).
376          */
377         if (val == 0x51)
378                 printk(KERN_INFO "smsc47m1: Found SMSC47B27x\n");
379         else if (val == 0x59)
380                 printk(KERN_INFO "smsc47m1: Found SMSC47M10x/SMSC47M13x\n");
381         else if (val == 0x5F)
382                 printk(KERN_INFO "smsc47m1: Found SMSC47M14x\n");
383         else {
384                 superio_exit();
385                 return -ENODEV;
386         }
387
388         superio_select();
389         *address = (superio_inb(SUPERIO_REG_BASE) << 8)
390                  |  superio_inb(SUPERIO_REG_BASE + 1);
391         val = superio_inb(SUPERIO_REG_ACT);
392         if (*address == 0 || (val & 0x01) == 0) {
393                 printk(KERN_INFO "smsc47m1: Device is disabled, will not use\n");
394                 superio_exit();
395                 return -ENODEV;
396         }
397
398         superio_exit();
399         return 0;
400 }
401
402 static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
403 {
404         struct i2c_client *new_client;
405         struct smsc47m1_data *data;
406         int err = 0;
407         int fan1, fan2, pwm1, pwm2;
408
409         if (!i2c_is_isa_adapter(adapter)) {
410                 return 0;
411         }
412
413         if (!request_region(address, SMSC_EXTENT, smsc47m1_driver.name)) {
414                 dev_err(&adapter->dev, "Region 0x%x already in use!\n", address);
415                 return -EBUSY;
416         }
417
418         if (!(data = kmalloc(sizeof(struct smsc47m1_data), GFP_KERNEL))) {
419                 err = -ENOMEM;
420                 goto error_release;
421         }
422         memset(data, 0x00, sizeof(struct smsc47m1_data));
423
424         new_client = &data->client;
425         i2c_set_clientdata(new_client, data);
426         new_client->addr = address;
427         init_MUTEX(&data->lock);
428         new_client->adapter = adapter;
429         new_client->driver = &smsc47m1_driver;
430         new_client->flags = 0;
431
432         strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
433         init_MUTEX(&data->update_lock);
434
435         /* If no function is properly configured, there's no point in
436            actually registering the chip. */
437         fan1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(0)) & 0x05)
438                == 0x05;
439         fan2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_TPIN(1)) & 0x05)
440                == 0x05;
441         pwm1 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(0)) & 0x05)
442                == 0x04;
443         pwm2 = (smsc47m1_read_value(new_client, SMSC47M1_REG_PPIN(1)) & 0x05)
444                == 0x04;
445         if (!(fan1 || fan2 || pwm1 || pwm2)) {
446                 dev_warn(&new_client->dev, "Device is not configured, will not use\n");
447                 err = -ENODEV;
448                 goto error_free;
449         }
450
451         if ((err = i2c_attach_client(new_client)))
452                 goto error_free;
453
454         /* Some values (fan min, clock dividers, pwm registers) may be
455            needed before any update is triggered, so we better read them
456            at least once here. We don't usually do it that way, but in
457            this particular case, manually reading 5 registers out of 8
458            doesn't make much sense and we're better using the existing
459            function. */
460         smsc47m1_update_device(&new_client->dev, 1);
461
462         if (fan1) {
463                 device_create_file(&new_client->dev, &dev_attr_fan1_input);
464                 device_create_file(&new_client->dev, &dev_attr_fan1_min);
465                 device_create_file(&new_client->dev, &dev_attr_fan1_div);
466         } else
467                 dev_dbg(&new_client->dev, "Fan 1 not enabled by hardware, "
468                         "skipping\n");
469
470         if (fan2) {
471                 device_create_file(&new_client->dev, &dev_attr_fan2_input);
472                 device_create_file(&new_client->dev, &dev_attr_fan2_min);
473                 device_create_file(&new_client->dev, &dev_attr_fan2_div);
474         } else
475                 dev_dbg(&new_client->dev, "Fan 2 not enabled by hardware, "
476                         "skipping\n");
477
478         if (pwm1) {
479                 device_create_file(&new_client->dev, &dev_attr_pwm1);
480                 device_create_file(&new_client->dev, &dev_attr_pwm1_enable);
481         } else
482                 dev_dbg(&new_client->dev, "PWM 1 not enabled by hardware, "
483                         "skipping\n");
484         if (pwm2) {
485                 device_create_file(&new_client->dev, &dev_attr_pwm2);
486                 device_create_file(&new_client->dev, &dev_attr_pwm2_enable);
487         } else
488                 dev_dbg(&new_client->dev, "PWM 2 not enabled by hardware, "
489                         "skipping\n");
490
491         device_create_file(&new_client->dev, &dev_attr_alarms);
492
493         return 0;
494
495 error_free:
496         kfree(new_client);
497 error_release:
498         release_region(address, SMSC_EXTENT);
499         return err;
500 }
501
502 static int smsc47m1_detach_client(struct i2c_client *client)
503 {
504         int err;
505
506         if ((err = i2c_detach_client(client))) {
507                 dev_err(&client->dev, "Client deregistration failed, "
508                         "client not detached.\n");
509                 return err;
510         }
511
512         release_region(client->addr, SMSC_EXTENT);
513         kfree(i2c_get_clientdata(client));
514
515         return 0;
516 }
517
518 static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
519 {
520         int res;
521
522         down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
523         res = inb_p(client->addr + reg);
524         up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
525         return res;
526 }
527
528 static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
529 {
530         down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
531         outb_p(value, client->addr + reg);
532         up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
533 }
534
535 static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
536                 int init)
537 {
538         struct i2c_client *client = to_i2c_client(dev);
539         struct smsc47m1_data *data = i2c_get_clientdata(client);
540
541         down(&data->update_lock);
542
543         if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
544                 int i;
545
546                 for (i = 0; i < 2; i++) {
547                         data->fan[i] = smsc47m1_read_value(client,
548                                        SMSC47M1_REG_FAN(i));
549                         data->fan_preload[i] = smsc47m1_read_value(client,
550                                                SMSC47M1_REG_FAN_PRELOAD(i));
551                         data->pwm[i] = smsc47m1_read_value(client,
552                                        SMSC47M1_REG_PWM(i));
553                 }
554
555                 i = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV);
556                 data->fan_div[0] = (i >> 4) & 0x03;
557                 data->fan_div[1] = i >> 6;
558
559                 data->alarms = smsc47m1_read_value(client,
560                                SMSC47M1_REG_ALARM) >> 6;
561                 /* Clear alarms if needed */
562                 if (data->alarms)
563                         smsc47m1_write_value(client, SMSC47M1_REG_ALARM, 0xC0);
564
565                 data->last_updated = jiffies;
566         }
567
568         up(&data->update_lock);
569         return data;
570 }
571
572 static int __init sm_smsc47m1_init(void)
573 {
574         if (smsc47m1_find(normal_isa)) {
575                 return -ENODEV;
576         }
577
578         return i2c_add_driver(&smsc47m1_driver);
579 }
580
581 static void __exit sm_smsc47m1_exit(void)
582 {
583         i2c_del_driver(&smsc47m1_driver);
584 }
585
586 MODULE_AUTHOR("Mark D. Studebaker <mdsxyz123@yahoo.com>");
587 MODULE_DESCRIPTION("SMSC LPC47M1xx fan sensors driver");
588 MODULE_LICENSE("GPL");
589
590 module_init(sm_smsc47m1_init);
591 module_exit(sm_smsc47m1_exit);