Merge git://git.kernel.org/pub/scm/linux/kernel/git/czankel/xtensa-2.6
[linux-2.6] / drivers / hwmon / fschmd.c
1 /* fschmd.c
2  *
3  * Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl>
4  *
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
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
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
17  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  */
19
20 /*
21  *  Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes,
22  *  Scylla, Heracles and Heimdall chips
23  *
24  *  Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6
25  *  (candidate) fschmd drivers:
26  *  Copyright (C) 2006 Thilo Cestonaro
27  *                      <thilo.cestonaro.external@fujitsu-siemens.com>
28  *  Copyright (C) 2004, 2005 Stefan Ott <stefan@desire.ch>
29  *  Copyright (C) 2003, 2004 Reinhard Nissl <rnissl@gmx.de>
30  *  Copyright (c) 2001 Martin Knoblauch <mkn@teraport.de, knobi@knobisoft.de>
31  *  Copyright (C) 2000 Hermann Jung <hej@odn.de>
32  */
33
34 #include <linux/module.h>
35 #include <linux/init.h>
36 #include <linux/slab.h>
37 #include <linux/jiffies.h>
38 #include <linux/i2c.h>
39 #include <linux/hwmon.h>
40 #include <linux/hwmon-sysfs.h>
41 #include <linux/err.h>
42 #include <linux/mutex.h>
43 #include <linux/sysfs.h>
44 #include <linux/dmi.h>
45
46 /* Addresses to scan */
47 static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
48
49 /* Insmod parameters */
50 I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
51
52 /*
53  * The FSCHMD registers and other defines
54  */
55
56 /* chip identification */
57 #define FSCHMD_REG_IDENT_0              0x00
58 #define FSCHMD_REG_IDENT_1              0x01
59 #define FSCHMD_REG_IDENT_2              0x02
60 #define FSCHMD_REG_REVISION             0x03
61
62 /* global control and status */
63 #define FSCHMD_REG_EVENT_STATE          0x04
64 #define FSCHMD_REG_CONTROL              0x05
65
66 #define FSCHMD_CONTROL_ALERT_LED_MASK   0x01
67
68 /* watchdog (support to be implemented) */
69 #define FSCHMD_REG_WDOG_PRESET          0x28
70 #define FSCHMD_REG_WDOG_STATE           0x23
71 #define FSCHMD_REG_WDOG_CONTROL         0x21
72
73 /* voltages, weird order is to keep the same order as the old drivers */
74 static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 };
75
76 /* minimum pwm at which the fan is driven (pwm can by increased depending on
77    the temp. Notice that for the scy some fans share there minimum speed.
78    Also notice that with the scy the sensor order is different than with the
79    other chips, this order was in the 2.4 driver and kept for consistency. */
80 static const u8 FSCHMD_REG_FAN_MIN[5][6] = {
81         { 0x55, 0x65 },                                 /* pos */
82         { 0x55, 0x65, 0xb5 },                           /* her */
83         { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 },         /* scy */
84         { 0x55, 0x65, 0xa5, 0xb5 },                     /* hrc */
85         { 0x55, 0x65, 0xa5, 0xb5, 0xc5 },               /* hmd */
86 };
87
88 /* actual fan speed */
89 static const u8 FSCHMD_REG_FAN_ACT[5][6] = {
90         { 0x0e, 0x6b, 0xab },                           /* pos */
91         { 0x0e, 0x6b, 0xbb },                           /* her */
92         { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb },         /* scy */
93         { 0x0e, 0x6b, 0xab, 0xbb },                     /* hrc */
94         { 0x5b, 0x6b, 0xab, 0xbb, 0xcb },               /* hmd */
95 };
96
97 /* fan status registers */
98 static const u8 FSCHMD_REG_FAN_STATE[5][6] = {
99         { 0x0d, 0x62, 0xa2 },                           /* pos */
100         { 0x0d, 0x62, 0xb2 },                           /* her */
101         { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 },         /* scy */
102         { 0x0d, 0x62, 0xa2, 0xb2 },                     /* hrc */
103         { 0x52, 0x62, 0xa2, 0xb2, 0xc2 },               /* hmd */
104 };
105
106 /* fan ripple / divider registers */
107 static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = {
108         { 0x0f, 0x6f, 0xaf },                           /* pos */
109         { 0x0f, 0x6f, 0xbf },                           /* her */
110         { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf },         /* scy */
111         { 0x0f, 0x6f, 0xaf, 0xbf },                     /* hrc */
112         { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf },               /* hmd */
113 };
114
115 static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 };
116
117 /* Fan status register bitmasks */
118 #define FSCHMD_FAN_ALARM_MASK           0x04 /* called fault by FSC! */
119 #define FSCHMD_FAN_NOT_PRESENT_MASK     0x08 /* not documented */
120
121
122 /* actual temperature registers */
123 static const u8 FSCHMD_REG_TEMP_ACT[5][5] = {
124         { 0x64, 0x32, 0x35 },                           /* pos */
125         { 0x64, 0x32, 0x35 },                           /* her */
126         { 0x64, 0xD0, 0x32, 0x35 },                     /* scy */
127         { 0x64, 0x32, 0x35 },                           /* hrc */
128         { 0x70, 0x80, 0x90, 0xd0, 0xe0 },               /* hmd */
129 };
130
131 /* temperature state registers */
132 static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
133         { 0x71, 0x81, 0x91 },                           /* pos */
134         { 0x71, 0x81, 0x91 },                           /* her */
135         { 0x71, 0xd1, 0x81, 0x91 },                     /* scy */
136         { 0x71, 0x81, 0x91 },                           /* hrc */
137         { 0x71, 0x81, 0x91, 0xd1, 0xe1 },               /* hmd */
138 };
139
140 /* temperature high limit registers, FSC does not document these. Proven to be
141    there with field testing on the fscher and fschrc, already supported / used
142    in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
143    at these addresses, but doesn't want to confirm they are the same as with
144    the fscher?? */
145 static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = {
146         { 0, 0, 0 },                                    /* pos */
147         { 0x76, 0x86, 0x96 },                           /* her */
148         { 0x76, 0xd6, 0x86, 0x96 },                     /* scy */
149         { 0x76, 0x86, 0x96 },                           /* hrc */
150         { 0x76, 0x86, 0x96, 0xd6, 0xe6 },               /* hmd */
151 };
152
153 /* These were found through experimenting with an fscher, currently they are
154    not used, but we keep them around for future reference.
155 static const u8 FSCHER_REG_TEMP_AUTOP1[] =      { 0x73, 0x83, 0x93 };
156 static const u8 FSCHER_REG_TEMP_AUTOP2[] =      { 0x75, 0x85, 0x95 }; */
157
158 static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
159
160 /* temp status register bitmasks */
161 #define FSCHMD_TEMP_WORKING_MASK        0x01
162 #define FSCHMD_TEMP_ALERT_MASK          0x02
163 /* there only really is an alarm if the sensor is working and alert == 1 */
164 #define FSCHMD_TEMP_ALARM_MASK \
165         (FSCHMD_TEMP_WORKING_MASK | FSCHMD_TEMP_ALERT_MASK)
166
167 /* our driver name */
168 #define FSCHMD_NAME "fschmd"
169
170 /*
171  * Functions declarations
172  */
173
174 static int fschmd_probe(struct i2c_client *client,
175                         const struct i2c_device_id *id);
176 static int fschmd_detect(struct i2c_client *client, int kind,
177                          struct i2c_board_info *info);
178 static int fschmd_remove(struct i2c_client *client);
179 static struct fschmd_data *fschmd_update_device(struct device *dev);
180
181 /*
182  * Driver data (common to all clients)
183  */
184
185 static const struct i2c_device_id fschmd_id[] = {
186         { "fscpos", fscpos },
187         { "fscher", fscher },
188         { "fscscy", fscscy },
189         { "fschrc", fschrc },
190         { "fschmd", fschmd },
191         { }
192 };
193 MODULE_DEVICE_TABLE(i2c, fschmd_id);
194
195 static struct i2c_driver fschmd_driver = {
196         .class          = I2C_CLASS_HWMON,
197         .driver = {
198                 .name   = FSCHMD_NAME,
199         },
200         .probe          = fschmd_probe,
201         .remove         = fschmd_remove,
202         .id_table       = fschmd_id,
203         .detect         = fschmd_detect,
204         .address_data   = &addr_data,
205 };
206
207 /*
208  * Client data (each client gets its own)
209  */
210
211 struct fschmd_data {
212         struct device *hwmon_dev;
213         struct mutex update_lock;
214         int kind;
215         char valid; /* zero until following fields are valid */
216         unsigned long last_updated; /* in jiffies */
217
218         /* register values */
219         u8 global_control;      /* global control register */
220         u8 volt[3];             /* 12, 5, battery voltage */
221         u8 temp_act[5];         /* temperature */
222         u8 temp_status[5];      /* status of sensor */
223         u8 temp_max[5];         /* high temp limit, notice: undocumented! */
224         u8 fan_act[6];          /* fans revolutions per second */
225         u8 fan_status[6];       /* fan status */
226         u8 fan_min[6];          /* fan min value for rps */
227         u8 fan_ripple[6];       /* divider for rps */
228 };
229
230 /* Global variables to hold information read from special DMI tables, which are
231    available on FSC machines with an fscher or later chip. */
232 static int dmi_mult[3] = { 490, 200, 100 };
233 static int dmi_offset[3] = { 0, 0, 0 };
234 static int dmi_vref = -1;
235
236
237 /*
238  * Sysfs attr show / store functions
239  */
240
241 static ssize_t show_in_value(struct device *dev,
242         struct device_attribute *devattr, char *buf)
243 {
244         const int max_reading[3] = { 14200, 6600, 3300 };
245         int index = to_sensor_dev_attr(devattr)->index;
246         struct fschmd_data *data = fschmd_update_device(dev);
247
248         /* fscher / fschrc - 1 as data->kind is an array index, not a chips */
249         if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1))
250                 return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref *
251                         dmi_mult[index]) / 255 + dmi_offset[index]);
252         else
253                 return sprintf(buf, "%d\n", (data->volt[index] *
254                         max_reading[index] + 128) / 255);
255 }
256
257
258 #define TEMP_FROM_REG(val)      (((val) - 128) * 1000)
259
260 static ssize_t show_temp_value(struct device *dev,
261         struct device_attribute *devattr, char *buf)
262 {
263         int index = to_sensor_dev_attr(devattr)->index;
264         struct fschmd_data *data = fschmd_update_device(dev);
265
266         return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[index]));
267 }
268
269 static ssize_t show_temp_max(struct device *dev,
270         struct device_attribute *devattr, char *buf)
271 {
272         int index = to_sensor_dev_attr(devattr)->index;
273         struct fschmd_data *data = fschmd_update_device(dev);
274
275         return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[index]));
276 }
277
278 static ssize_t store_temp_max(struct device *dev, struct device_attribute
279         *devattr, const char *buf, size_t count)
280 {
281         int index = to_sensor_dev_attr(devattr)->index;
282         struct fschmd_data *data = dev_get_drvdata(dev);
283         long v = simple_strtol(buf, NULL, 10) / 1000;
284
285         v = SENSORS_LIMIT(v, -128, 127) + 128;
286
287         mutex_lock(&data->update_lock);
288         i2c_smbus_write_byte_data(to_i2c_client(dev),
289                 FSCHMD_REG_TEMP_LIMIT[data->kind][index], v);
290         data->temp_max[index] = v;
291         mutex_unlock(&data->update_lock);
292
293         return count;
294 }
295
296 static ssize_t show_temp_fault(struct device *dev,
297         struct device_attribute *devattr, char *buf)
298 {
299         int index = to_sensor_dev_attr(devattr)->index;
300         struct fschmd_data *data = fschmd_update_device(dev);
301
302         /* bit 0 set means sensor working ok, so no fault! */
303         if (data->temp_status[index] & FSCHMD_TEMP_WORKING_MASK)
304                 return sprintf(buf, "0\n");
305         else
306                 return sprintf(buf, "1\n");
307 }
308
309 static ssize_t show_temp_alarm(struct device *dev,
310         struct device_attribute *devattr, char *buf)
311 {
312         int index = to_sensor_dev_attr(devattr)->index;
313         struct fschmd_data *data = fschmd_update_device(dev);
314
315         if ((data->temp_status[index] & FSCHMD_TEMP_ALARM_MASK) ==
316                         FSCHMD_TEMP_ALARM_MASK)
317                 return sprintf(buf, "1\n");
318         else
319                 return sprintf(buf, "0\n");
320 }
321
322
323 #define RPM_FROM_REG(val)       ((val) * 60)
324
325 static ssize_t show_fan_value(struct device *dev,
326         struct device_attribute *devattr, char *buf)
327 {
328         int index = to_sensor_dev_attr(devattr)->index;
329         struct fschmd_data *data = fschmd_update_device(dev);
330
331         return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[index]));
332 }
333
334 static ssize_t show_fan_div(struct device *dev,
335         struct device_attribute *devattr, char *buf)
336 {
337         int index = to_sensor_dev_attr(devattr)->index;
338         struct fschmd_data *data = fschmd_update_device(dev);
339
340         /* bits 2..7 reserved => mask with 3 */
341         return sprintf(buf, "%d\n", 1 << (data->fan_ripple[index] & 3));
342 }
343
344 static ssize_t store_fan_div(struct device *dev, struct device_attribute
345         *devattr, const char *buf, size_t count)
346 {
347         u8 reg;
348         int index = to_sensor_dev_attr(devattr)->index;
349         struct fschmd_data *data = dev_get_drvdata(dev);
350         /* supported values: 2, 4, 8 */
351         unsigned long v = simple_strtoul(buf, NULL, 10);
352
353         switch (v) {
354         case 2: v = 1; break;
355         case 4: v = 2; break;
356         case 8: v = 3; break;
357         default:
358                 dev_err(dev, "fan_div value %lu not supported. "
359                         "Choose one of 2, 4 or 8!\n", v);
360                 return -EINVAL;
361         }
362
363         mutex_lock(&data->update_lock);
364
365         reg = i2c_smbus_read_byte_data(to_i2c_client(dev),
366                 FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
367
368         /* bits 2..7 reserved => mask with 0x03 */
369         reg &= ~0x03;
370         reg |= v;
371
372         i2c_smbus_write_byte_data(to_i2c_client(dev),
373                 FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg);
374
375         data->fan_ripple[index] = reg;
376
377         mutex_unlock(&data->update_lock);
378
379         return count;
380 }
381
382 static ssize_t show_fan_alarm(struct device *dev,
383         struct device_attribute *devattr, char *buf)
384 {
385         int index = to_sensor_dev_attr(devattr)->index;
386         struct fschmd_data *data = fschmd_update_device(dev);
387
388         if (data->fan_status[index] & FSCHMD_FAN_ALARM_MASK)
389                 return sprintf(buf, "1\n");
390         else
391                 return sprintf(buf, "0\n");
392 }
393
394 static ssize_t show_fan_fault(struct device *dev,
395         struct device_attribute *devattr, char *buf)
396 {
397         int index = to_sensor_dev_attr(devattr)->index;
398         struct fschmd_data *data = fschmd_update_device(dev);
399
400         if (data->fan_status[index] & FSCHMD_FAN_NOT_PRESENT_MASK)
401                 return sprintf(buf, "1\n");
402         else
403                 return sprintf(buf, "0\n");
404 }
405
406
407 static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
408         struct device_attribute *devattr, char *buf)
409 {
410         int index = to_sensor_dev_attr(devattr)->index;
411         int val = fschmd_update_device(dev)->fan_min[index];
412
413         /* 0 = allow turning off, 1-255 = 50-100% */
414         if (val)
415                 val = val / 2 + 128;
416
417         return sprintf(buf, "%d\n", val);
418 }
419
420 static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
421         struct device_attribute *devattr, const char *buf, size_t count)
422 {
423         int index = to_sensor_dev_attr(devattr)->index;
424         struct fschmd_data *data = dev_get_drvdata(dev);
425         unsigned long v = simple_strtoul(buf, NULL, 10);
426
427         /* register: 0 = allow turning off, 1-255 = 50-100% */
428         if (v) {
429                 v = SENSORS_LIMIT(v, 128, 255);
430                 v = (v - 128) * 2 + 1;
431         }
432
433         mutex_lock(&data->update_lock);
434
435         i2c_smbus_write_byte_data(to_i2c_client(dev),
436                 FSCHMD_REG_FAN_MIN[data->kind][index], v);
437         data->fan_min[index] = v;
438
439         mutex_unlock(&data->update_lock);
440
441         return count;
442 }
443
444
445 /* The FSC hwmon family has the ability to force an attached alert led to flash
446    from software, we export this as an alert_led sysfs attr */
447 static ssize_t show_alert_led(struct device *dev,
448         struct device_attribute *devattr, char *buf)
449 {
450         struct fschmd_data *data = fschmd_update_device(dev);
451
452         if (data->global_control & FSCHMD_CONTROL_ALERT_LED_MASK)
453                 return sprintf(buf, "1\n");
454         else
455                 return sprintf(buf, "0\n");
456 }
457
458 static ssize_t store_alert_led(struct device *dev,
459         struct device_attribute *devattr, const char *buf, size_t count)
460 {
461         u8 reg;
462         struct fschmd_data *data = dev_get_drvdata(dev);
463         unsigned long v = simple_strtoul(buf, NULL, 10);
464
465         mutex_lock(&data->update_lock);
466
467         reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
468
469         if (v)
470                 reg |= FSCHMD_CONTROL_ALERT_LED_MASK;
471         else
472                 reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK;
473
474         i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
475
476         data->global_control = reg;
477
478         mutex_unlock(&data->update_lock);
479
480         return count;
481 }
482
483 static struct sensor_device_attribute fschmd_attr[] = {
484         SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
485         SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
486         SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
487         SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0),
488 };
489
490 static struct sensor_device_attribute fschmd_temp_attr[] = {
491         SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0),
492         SENSOR_ATTR(temp1_max,   0644, show_temp_max, store_temp_max, 0),
493         SENSOR_ATTR(temp1_fault, 0444, show_temp_fault, NULL, 0),
494         SENSOR_ATTR(temp1_alarm, 0444, show_temp_alarm, NULL, 0),
495         SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1),
496         SENSOR_ATTR(temp2_max,   0644, show_temp_max, store_temp_max, 1),
497         SENSOR_ATTR(temp2_fault, 0444, show_temp_fault, NULL, 1),
498         SENSOR_ATTR(temp2_alarm, 0444, show_temp_alarm, NULL, 1),
499         SENSOR_ATTR(temp3_input, 0444, show_temp_value, NULL, 2),
500         SENSOR_ATTR(temp3_max,   0644, show_temp_max, store_temp_max, 2),
501         SENSOR_ATTR(temp3_fault, 0444, show_temp_fault, NULL, 2),
502         SENSOR_ATTR(temp3_alarm, 0444, show_temp_alarm, NULL, 2),
503         SENSOR_ATTR(temp4_input, 0444, show_temp_value, NULL, 3),
504         SENSOR_ATTR(temp4_max,   0644, show_temp_max, store_temp_max, 3),
505         SENSOR_ATTR(temp4_fault, 0444, show_temp_fault, NULL, 3),
506         SENSOR_ATTR(temp4_alarm, 0444, show_temp_alarm, NULL, 3),
507         SENSOR_ATTR(temp5_input, 0444, show_temp_value, NULL, 4),
508         SENSOR_ATTR(temp5_max,   0644, show_temp_max, store_temp_max, 4),
509         SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
510         SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
511 };
512
513 static struct sensor_device_attribute fschmd_fan_attr[] = {
514         SENSOR_ATTR(fan1_input, 0444, show_fan_value, NULL, 0),
515         SENSOR_ATTR(fan1_div,   0644, show_fan_div, store_fan_div, 0),
516         SENSOR_ATTR(fan1_alarm, 0444, show_fan_alarm, NULL, 0),
517         SENSOR_ATTR(fan1_fault, 0444, show_fan_fault, NULL, 0),
518         SENSOR_ATTR(pwm1_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
519                 store_pwm_auto_point1_pwm, 0),
520         SENSOR_ATTR(fan2_input, 0444, show_fan_value, NULL, 1),
521         SENSOR_ATTR(fan2_div,   0644, show_fan_div, store_fan_div, 1),
522         SENSOR_ATTR(fan2_alarm, 0444, show_fan_alarm, NULL, 1),
523         SENSOR_ATTR(fan2_fault, 0444, show_fan_fault, NULL, 1),
524         SENSOR_ATTR(pwm2_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
525                 store_pwm_auto_point1_pwm, 1),
526         SENSOR_ATTR(fan3_input, 0444, show_fan_value, NULL, 2),
527         SENSOR_ATTR(fan3_div,   0644, show_fan_div, store_fan_div, 2),
528         SENSOR_ATTR(fan3_alarm, 0444, show_fan_alarm, NULL, 2),
529         SENSOR_ATTR(fan3_fault, 0444, show_fan_fault, NULL, 2),
530         SENSOR_ATTR(pwm3_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
531                 store_pwm_auto_point1_pwm, 2),
532         SENSOR_ATTR(fan4_input, 0444, show_fan_value, NULL, 3),
533         SENSOR_ATTR(fan4_div,   0644, show_fan_div, store_fan_div, 3),
534         SENSOR_ATTR(fan4_alarm, 0444, show_fan_alarm, NULL, 3),
535         SENSOR_ATTR(fan4_fault, 0444, show_fan_fault, NULL, 3),
536         SENSOR_ATTR(pwm4_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
537                 store_pwm_auto_point1_pwm, 3),
538         SENSOR_ATTR(fan5_input, 0444, show_fan_value, NULL, 4),
539         SENSOR_ATTR(fan5_div,   0644, show_fan_div, store_fan_div, 4),
540         SENSOR_ATTR(fan5_alarm, 0444, show_fan_alarm, NULL, 4),
541         SENSOR_ATTR(fan5_fault, 0444, show_fan_fault, NULL, 4),
542         SENSOR_ATTR(pwm5_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
543                 store_pwm_auto_point1_pwm, 4),
544         SENSOR_ATTR(fan6_input, 0444, show_fan_value, NULL, 5),
545         SENSOR_ATTR(fan6_div,   0644, show_fan_div, store_fan_div, 5),
546         SENSOR_ATTR(fan6_alarm, 0444, show_fan_alarm, NULL, 5),
547         SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
548         SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
549                 store_pwm_auto_point1_pwm, 5),
550 };
551
552
553 /*
554  * Real code
555  */
556
557 /* DMI decode routine to read voltage scaling factors from special DMI tables,
558    which are available on FSC machines with an fscher or later chip. */
559 static void fschmd_dmi_decode(const struct dmi_header *header)
560 {
561         int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
562
563         /* dmi code ugliness, we get passed the address of the contents of
564            a complete DMI record, but in the form of a dmi_header pointer, in
565            reality this address holds header->length bytes of which the header
566            are the first 4 bytes */
567         u8 *dmi_data = (u8 *)header;
568
569         /* We are looking for OEM-specific type 185 */
570         if (header->type != 185)
571                 return;
572
573         /* we are looking for what Siemens calls "subtype" 19, the subtype
574            is stored in byte 5 of the dmi block */
575         if (header->length < 5 || dmi_data[4] != 19)
576                 return;
577
578         /* After the subtype comes 1 unknown byte and then blocks of 5 bytes,
579            consisting of what Siemens calls an "Entity" number, followed by
580            2 16-bit words in LSB first order */
581         for (i = 6; (i + 4) < header->length; i += 5) {
582                 /* entity 1 - 3: voltage multiplier and offset */
583                 if (dmi_data[i] >= 1 && dmi_data[i] <= 3) {
584                         /* Our in sensors order and the DMI order differ */
585                         const int shuffle[3] = { 1, 0, 2 };
586                         int in = shuffle[dmi_data[i] - 1];
587
588                         /* Check for twice the same entity */
589                         if (found & (1 << in))
590                                 return;
591
592                         mult[in] = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
593                         offset[in] = dmi_data[i + 3] | (dmi_data[i + 4] << 8);
594
595                         found |= 1 << in;
596                 }
597
598                 /* entity 7: reference voltage */
599                 if (dmi_data[i] == 7) {
600                         /* Check for twice the same entity */
601                         if (found & 0x08)
602                                 return;
603
604                         vref = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
605
606                         found |= 0x08;
607                 }
608         }
609
610         if (found == 0x0F) {
611                 for (i = 0; i < 3; i++) {
612                         dmi_mult[i] = mult[i] * 10;
613                         dmi_offset[i] = offset[i] * 10;
614                 }
615                 dmi_vref = vref;
616         }
617 }
618
619 static int fschmd_detect(struct i2c_client *client, int kind,
620                          struct i2c_board_info *info)
621 {
622         struct i2c_adapter *adapter = client->adapter;
623         const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
624                                                 "fschrc", "fschmd" };
625
626         if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
627                 return -ENODEV;
628
629         /* Detect & Identify the chip */
630         if (kind <= 0) {
631                 char id[4];
632
633                 id[0] = i2c_smbus_read_byte_data(client,
634                                 FSCHMD_REG_IDENT_0);
635                 id[1] = i2c_smbus_read_byte_data(client,
636                                 FSCHMD_REG_IDENT_1);
637                 id[2] = i2c_smbus_read_byte_data(client,
638                                 FSCHMD_REG_IDENT_2);
639                 id[3] = '\0';
640
641                 if (!strcmp(id, "PEG"))
642                         kind = fscpos;
643                 else if (!strcmp(id, "HER"))
644                         kind = fscher;
645                 else if (!strcmp(id, "SCY"))
646                         kind = fscscy;
647                 else if (!strcmp(id, "HRC"))
648                         kind = fschrc;
649                 else if (!strcmp(id, "HMD"))
650                         kind = fschmd;
651                 else
652                         return -ENODEV;
653         }
654
655         strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
656
657         return 0;
658 }
659
660 static int fschmd_probe(struct i2c_client *client,
661                         const struct i2c_device_id *id)
662 {
663         struct fschmd_data *data;
664         u8 revision;
665         const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
666                                         "Heracles", "Heimdall" };
667         int i, err;
668         enum chips kind = id->driver_data;
669
670         data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL);
671         if (!data)
672                 return -ENOMEM;
673
674         i2c_set_clientdata(client, data);
675         mutex_init(&data->update_lock);
676
677         if (kind == fscpos) {
678                 /* The Poseidon has hardwired temp limits, fill these
679                    in for the alarm resetting code */
680                 data->temp_max[0] = 70 + 128;
681                 data->temp_max[1] = 50 + 128;
682                 data->temp_max[2] = 50 + 128;
683         }
684
685         /* Read the special DMI table for fscher and newer chips */
686         if (kind == fscher || kind >= fschrc) {
687                 dmi_walk(fschmd_dmi_decode);
688                 if (dmi_vref == -1) {
689                         printk(KERN_WARNING FSCHMD_NAME
690                                 ": Couldn't get voltage scaling factors from "
691                                 "BIOS DMI table, using builtin defaults\n");
692                         dmi_vref = 33;
693                 }
694         }
695
696         /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
697         data->kind = kind - 1;
698
699         for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
700                 err = device_create_file(&client->dev,
701                                         &fschmd_attr[i].dev_attr);
702                 if (err)
703                         goto exit_detach;
704         }
705
706         for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++) {
707                 /* Poseidon doesn't have TEMP_LIMIT registers */
708                 if (kind == fscpos && fschmd_temp_attr[i].dev_attr.show ==
709                                 show_temp_max)
710                         continue;
711
712                 err = device_create_file(&client->dev,
713                                         &fschmd_temp_attr[i].dev_attr);
714                 if (err)
715                         goto exit_detach;
716         }
717
718         for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++) {
719                 /* Poseidon doesn't have a FAN_MIN register for its 3rd fan */
720                 if (kind == fscpos &&
721                                 !strcmp(fschmd_fan_attr[i].dev_attr.attr.name,
722                                         "pwm3_auto_point1_pwm"))
723                         continue;
724
725                 err = device_create_file(&client->dev,
726                                         &fschmd_fan_attr[i].dev_attr);
727                 if (err)
728                         goto exit_detach;
729         }
730
731         data->hwmon_dev = hwmon_device_register(&client->dev);
732         if (IS_ERR(data->hwmon_dev)) {
733                 err = PTR_ERR(data->hwmon_dev);
734                 data->hwmon_dev = NULL;
735                 goto exit_detach;
736         }
737
738         revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
739         printk(KERN_INFO FSCHMD_NAME ": Detected FSC %s chip, revision: %d\n",
740                 names[data->kind], (int) revision);
741
742         return 0;
743
744 exit_detach:
745         fschmd_remove(client); /* will also free data for us */
746         return err;
747 }
748
749 static int fschmd_remove(struct i2c_client *client)
750 {
751         struct fschmd_data *data = i2c_get_clientdata(client);
752         int i;
753
754         /* Check if registered in case we're called from fschmd_detect
755            to cleanup after an error */
756         if (data->hwmon_dev)
757                 hwmon_device_unregister(data->hwmon_dev);
758
759         for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++)
760                 device_remove_file(&client->dev, &fschmd_attr[i].dev_attr);
761         for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++)
762                 device_remove_file(&client->dev,
763                                         &fschmd_temp_attr[i].dev_attr);
764         for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++)
765                 device_remove_file(&client->dev,
766                                         &fschmd_fan_attr[i].dev_attr);
767
768         kfree(data);
769         return 0;
770 }
771
772 static struct fschmd_data *fschmd_update_device(struct device *dev)
773 {
774         struct i2c_client *client = to_i2c_client(dev);
775         struct fschmd_data *data = i2c_get_clientdata(client);
776         int i;
777
778         mutex_lock(&data->update_lock);
779
780         if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
781
782                 for (i = 0; i < FSCHMD_NO_TEMP_SENSORS[data->kind]; i++) {
783                         data->temp_act[i] = i2c_smbus_read_byte_data(client,
784                                         FSCHMD_REG_TEMP_ACT[data->kind][i]);
785                         data->temp_status[i] = i2c_smbus_read_byte_data(client,
786                                         FSCHMD_REG_TEMP_STATE[data->kind][i]);
787
788                         /* The fscpos doesn't have TEMP_LIMIT registers */
789                         if (FSCHMD_REG_TEMP_LIMIT[data->kind][i])
790                                 data->temp_max[i] = i2c_smbus_read_byte_data(
791                                         client,
792                                         FSCHMD_REG_TEMP_LIMIT[data->kind][i]);
793
794                         /* reset alarm if the alarm condition is gone,
795                            the chip doesn't do this itself */
796                         if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) ==
797                                         FSCHMD_TEMP_ALARM_MASK &&
798                                         data->temp_act[i] < data->temp_max[i])
799                                 i2c_smbus_write_byte_data(client,
800                                         FSCHMD_REG_TEMP_STATE[data->kind][i],
801                                         FSCHMD_TEMP_ALERT_MASK);
802                 }
803
804                 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
805                         data->fan_act[i] = i2c_smbus_read_byte_data(client,
806                                         FSCHMD_REG_FAN_ACT[data->kind][i]);
807                         data->fan_status[i] = i2c_smbus_read_byte_data(client,
808                                         FSCHMD_REG_FAN_STATE[data->kind][i]);
809                         data->fan_ripple[i] = i2c_smbus_read_byte_data(client,
810                                         FSCHMD_REG_FAN_RIPPLE[data->kind][i]);
811
812                         /* The fscpos third fan doesn't have a fan_min */
813                         if (FSCHMD_REG_FAN_MIN[data->kind][i])
814                                 data->fan_min[i] = i2c_smbus_read_byte_data(
815                                         client,
816                                         FSCHMD_REG_FAN_MIN[data->kind][i]);
817
818                         /* reset fan status if speed is back to > 0 */
819                         if ((data->fan_status[i] & FSCHMD_FAN_ALARM_MASK) &&
820                                         data->fan_act[i])
821                                 i2c_smbus_write_byte_data(client,
822                                         FSCHMD_REG_FAN_STATE[data->kind][i],
823                                         FSCHMD_FAN_ALARM_MASK);
824                 }
825
826                 for (i = 0; i < 3; i++)
827                         data->volt[i] = i2c_smbus_read_byte_data(client,
828                                                 FSCHMD_REG_VOLT[i]);
829
830                 data->global_control = i2c_smbus_read_byte_data(client,
831                                                 FSCHMD_REG_CONTROL);
832
833                 /* To be implemented in the future
834                 data->watchdog[0] = i2c_smbus_read_byte_data(client,
835                                                 FSCHMD_REG_WDOG_PRESET);
836                 data->watchdog[1] = i2c_smbus_read_byte_data(client,
837                                                 FSCHMD_REG_WDOG_STATE);
838                 data->watchdog[2] = i2c_smbus_read_byte_data(client,
839                                                 FSCHMD_REG_WDOG_CONTROL); */
840
841                 data->last_updated = jiffies;
842                 data->valid = 1;
843         }
844
845         mutex_unlock(&data->update_lock);
846
847         return data;
848 }
849
850 static int __init fschmd_init(void)
851 {
852         return i2c_add_driver(&fschmd_driver);
853 }
854
855 static void __exit fschmd_exit(void)
856 {
857         i2c_del_driver(&fschmd_driver);
858 }
859
860 MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
861 MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
862                         "Heimdall driver");
863 MODULE_LICENSE("GPL");
864
865 module_init(fschmd_init);
866 module_exit(fschmd_exit);