blob: 96717036893376dd47ae06134af682e439640b0d [file] [log] [blame]
Hans de Goede569ff102007-10-11 08:06:29 -04001/* 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>
Hans de Goede7845cd72007-12-20 16:42:59 +010044#include <linux/dmi.h>
Hans de Goede569ff102007-10-11 08:06:29 -040045
46/* Addresses to scan */
Mark M. Hoffman25e9c862008-02-17 22:28:03 -050047static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
Hans de Goede569ff102007-10-11 08:06:29 -040048
49/* Insmod parameters */
50I2C_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 */
74static 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 then with the
79 other chips, this order was in the 2.4 driver and kept for consistency. */
80static 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 */
89static 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 */
98static 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 */
107static 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
115static 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 */
123static 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 */
132static 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 */
Jean Delvare7dcf9a32007-11-24 17:45:09 -0500137 { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */
Hans de Goede569ff102007-10-11 08:06:29 -0400138};
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?? */
145static 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 */
Jean Delvare7dcf9a32007-11-24 17:45:09 -0500150 { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */
Hans de Goede569ff102007-10-11 08:06:29 -0400151};
152
153/* These were found through experimenting with an fscher, currently they are
154 not used, but we keep them around for future reference.
155static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 };
156static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */
157
158static 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200174static int fschmd_probe(struct i2c_client *client,
175 const struct i2c_device_id *id);
176static int fschmd_detect(struct i2c_client *client, int kind,
177 struct i2c_board_info *info);
178static int fschmd_remove(struct i2c_client *client);
Hans de Goede569ff102007-10-11 08:06:29 -0400179static struct fschmd_data *fschmd_update_device(struct device *dev);
180
181/*
182 * Driver data (common to all clients)
183 */
184
Jean Delvare40ac1992008-07-16 19:30:12 +0200185static const struct i2c_device_id fschmd_id[] = {
186 { "fscpos", fscpos },
187 { "fscher", fscher },
188 { "fscscy", fscscy },
189 { "fschrc", fschrc },
190 { "fschmd", fschmd },
191 { }
192};
193MODULE_DEVICE_TABLE(i2c, fschmd_id);
194
Hans de Goede569ff102007-10-11 08:06:29 -0400195static struct i2c_driver fschmd_driver = {
Jean Delvare40ac1992008-07-16 19:30:12 +0200196 .class = I2C_CLASS_HWMON,
Hans de Goede569ff102007-10-11 08:06:29 -0400197 .driver = {
198 .name = FSCHMD_NAME,
199 },
Jean Delvare40ac1992008-07-16 19:30:12 +0200200 .probe = fschmd_probe,
201 .remove = fschmd_remove,
202 .id_table = fschmd_id,
203 .detect = fschmd_detect,
204 .address_data = &addr_data,
Hans de Goede569ff102007-10-11 08:06:29 -0400205};
206
207/*
208 * Client data (each client gets its own)
209 */
210
211struct fschmd_data {
Hans de Goede569ff102007-10-11 08:06:29 -0400212 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
Hans de Goede7845cd72007-12-20 16:42:59 +0100230/* Global variables to hold information read from special DMI tables, which are
231 available on FSC machines with an fscher or later chip. */
232static int dmi_mult[3] = { 490, 200, 100 };
233static int dmi_offset[3] = { 0, 0, 0 };
234static int dmi_vref = -1;
235
236
Hans de Goede569ff102007-10-11 08:06:29 -0400237/*
238 * Sysfs attr show / store functions
239 */
240
241static 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
Hans de Goede7845cd72007-12-20 16:42:59 +0100248 /* 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);
Hans de Goede569ff102007-10-11 08:06:29 -0400255}
256
257
258#define TEMP_FROM_REG(val) (((val) - 128) * 1000)
259
260static 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
269static 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
278static 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);
Jean Delvare40ac1992008-07-16 19:30:12 +0200288 i2c_smbus_write_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400289 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
296static 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
309static 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
325static 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
334static 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
344static 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200365 reg = i2c_smbus_read_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400366 FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
367
368 /* bits 2..7 reserved => mask with 0x03 */
369 reg &= ~0x03;
370 reg |= v;
371
Jean Delvare40ac1992008-07-16 19:30:12 +0200372 i2c_smbus_write_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400373 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
382static 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
394static 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
407static 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
420static 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200435 i2c_smbus_write_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400436 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 */
447static 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
458static 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200467 reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
Hans de Goede569ff102007-10-11 08:06:29 -0400468
469 if (v)
470 reg |= FSCHMD_CONTROL_ALERT_LED_MASK;
471 else
472 reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK;
473
Jean Delvare40ac1992008-07-16 19:30:12 +0200474 i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
Hans de Goede569ff102007-10-11 08:06:29 -0400475
476 data->global_control = reg;
477
478 mutex_unlock(&data->update_lock);
479
480 return count;
481}
482
483static 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
490static 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
513static 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
Hans de Goede7845cd72007-12-20 16:42:59 +0100557/* 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. */
559static 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200619static int fschmd_detect(struct i2c_client *client, int kind,
620 struct i2c_board_info *info)
Hans de Goede569ff102007-10-11 08:06:29 -0400621{
Jean Delvare40ac1992008-07-16 19:30:12 +0200622 struct i2c_adapter *adapter = client->adapter;
Hans de Goede569ff102007-10-11 08:06:29 -0400623 const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
624 "fschrc", "fschmd" };
Hans de Goede569ff102007-10-11 08:06:29 -0400625
626 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
Jean Delvare40ac1992008-07-16 19:30:12 +0200627 return -ENODEV;
Hans de Goede569ff102007-10-11 08:06:29 -0400628
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
Jean Delvare40ac1992008-07-16 19:30:12 +0200652 return -ENODEV;
Hans de Goede569ff102007-10-11 08:06:29 -0400653 }
654
Jean Delvare40ac1992008-07-16 19:30:12 +0200655 strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
656
657 return 0;
658}
659
660static 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
Hans de Goede569ff102007-10-11 08:06:29 -0400677 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
Hans de Goede7845cd72007-12-20 16:42:59 +0100685 /* 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
Hans de Goede569ff102007-10-11 08:06:29 -0400696 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
697 data->kind = kind - 1;
Hans de Goede569ff102007-10-11 08:06:29 -0400698
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
744exit_detach:
Jean Delvare40ac1992008-07-16 19:30:12 +0200745 fschmd_remove(client); /* will also free data for us */
Hans de Goede569ff102007-10-11 08:06:29 -0400746 return err;
747}
748
Jean Delvare40ac1992008-07-16 19:30:12 +0200749static int fschmd_remove(struct i2c_client *client)
Hans de Goede569ff102007-10-11 08:06:29 -0400750{
751 struct fschmd_data *data = i2c_get_clientdata(client);
Jean Delvare40ac1992008-07-16 19:30:12 +0200752 int i;
Hans de Goede569ff102007-10-11 08:06:29 -0400753
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
Hans de Goede569ff102007-10-11 08:06:29 -0400768 kfree(data);
769 return 0;
770}
771
772static 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
850static int __init fschmd_init(void)
851{
852 return i2c_add_driver(&fschmd_driver);
853}
854
855static void __exit fschmd_exit(void)
856{
857 i2c_del_driver(&fschmd_driver);
858}
859
860MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
861MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
862 "Heimdall driver");
863MODULE_LICENSE("GPL");
864
865module_init(fschmd_init);
866module_exit(fschmd_exit);