Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs...
[linux-2.6-block.git] / drivers / hwmon / fschmd.c
CommitLineData
569ff102
HG
1/* fschmd.c
2 *
453e308d 3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
569ff102
HG
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>
7845cd79 44#include <linux/dmi.h>
97950c3d
HG
45#include <linux/fs.h>
46#include <linux/watchdog.h>
47#include <linux/miscdevice.h>
48#include <linux/uaccess.h>
49#include <linux/kref.h>
569ff102
HG
50
51/* Addresses to scan */
25e9c86d 52static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
569ff102
HG
53
54/* Insmod parameters */
97950c3d
HG
55static int nowayout = WATCHDOG_NOWAYOUT;
56module_param(nowayout, int, 0);
57MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
58 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
569ff102
HG
59I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
60
61/*
62 * The FSCHMD registers and other defines
63 */
64
65/* chip identification */
66#define FSCHMD_REG_IDENT_0 0x00
67#define FSCHMD_REG_IDENT_1 0x01
68#define FSCHMD_REG_IDENT_2 0x02
69#define FSCHMD_REG_REVISION 0x03
70
71/* global control and status */
72#define FSCHMD_REG_EVENT_STATE 0x04
73#define FSCHMD_REG_CONTROL 0x05
74
453e308d 75#define FSCHMD_CONTROL_ALERT_LED 0x01
569ff102 76
97950c3d 77/* watchdog */
569ff102
HG
78#define FSCHMD_REG_WDOG_PRESET 0x28
79#define FSCHMD_REG_WDOG_STATE 0x23
80#define FSCHMD_REG_WDOG_CONTROL 0x21
81
97950c3d
HG
82#define FSCHMD_WDOG_CONTROL_TRIGGER 0x10
83#define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */
84#define FSCHMD_WDOG_CONTROL_STOP 0x20
85#define FSCHMD_WDOG_CONTROL_RESOLUTION 0x40
86
87#define FSCHMD_WDOG_STATE_CARDRESET 0x02
88
569ff102
HG
89/* voltages, weird order is to keep the same order as the old drivers */
90static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 };
91
92/* minimum pwm at which the fan is driven (pwm can by increased depending on
93 the temp. Notice that for the scy some fans share there minimum speed.
025dfdaf 94 Also notice that with the scy the sensor order is different than with the
569ff102
HG
95 other chips, this order was in the 2.4 driver and kept for consistency. */
96static const u8 FSCHMD_REG_FAN_MIN[5][6] = {
97 { 0x55, 0x65 }, /* pos */
98 { 0x55, 0x65, 0xb5 }, /* her */
99 { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */
100 { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */
101 { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */
102};
103
104/* actual fan speed */
105static const u8 FSCHMD_REG_FAN_ACT[5][6] = {
106 { 0x0e, 0x6b, 0xab }, /* pos */
107 { 0x0e, 0x6b, 0xbb }, /* her */
108 { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */
109 { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */
110 { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */
111};
112
113/* fan status registers */
114static const u8 FSCHMD_REG_FAN_STATE[5][6] = {
115 { 0x0d, 0x62, 0xa2 }, /* pos */
116 { 0x0d, 0x62, 0xb2 }, /* her */
117 { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */
118 { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */
119 { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */
120};
121
122/* fan ripple / divider registers */
123static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = {
124 { 0x0f, 0x6f, 0xaf }, /* pos */
125 { 0x0f, 0x6f, 0xbf }, /* her */
126 { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */
127 { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */
128 { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */
129};
130
131static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 };
132
133/* Fan status register bitmasks */
453e308d
HG
134#define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */
135#define FSCHMD_FAN_NOT_PRESENT 0x08 /* not documented */
569ff102
HG
136
137
138/* actual temperature registers */
139static const u8 FSCHMD_REG_TEMP_ACT[5][5] = {
140 { 0x64, 0x32, 0x35 }, /* pos */
141 { 0x64, 0x32, 0x35 }, /* her */
142 { 0x64, 0xD0, 0x32, 0x35 }, /* scy */
143 { 0x64, 0x32, 0x35 }, /* hrc */
144 { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */
145};
146
147/* temperature state registers */
148static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
149 { 0x71, 0x81, 0x91 }, /* pos */
150 { 0x71, 0x81, 0x91 }, /* her */
151 { 0x71, 0xd1, 0x81, 0x91 }, /* scy */
152 { 0x71, 0x81, 0x91 }, /* hrc */
7dcf9a31 153 { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */
569ff102
HG
154};
155
156/* temperature high limit registers, FSC does not document these. Proven to be
157 there with field testing on the fscher and fschrc, already supported / used
158 in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
159 at these addresses, but doesn't want to confirm they are the same as with
160 the fscher?? */
161static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = {
162 { 0, 0, 0 }, /* pos */
163 { 0x76, 0x86, 0x96 }, /* her */
164 { 0x76, 0xd6, 0x86, 0x96 }, /* scy */
165 { 0x76, 0x86, 0x96 }, /* hrc */
7dcf9a31 166 { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */
569ff102
HG
167};
168
169/* These were found through experimenting with an fscher, currently they are
170 not used, but we keep them around for future reference.
171static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 };
172static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */
173
174static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
175
176/* temp status register bitmasks */
453e308d
HG
177#define FSCHMD_TEMP_WORKING 0x01
178#define FSCHMD_TEMP_ALERT 0x02
569ff102
HG
179/* there only really is an alarm if the sensor is working and alert == 1 */
180#define FSCHMD_TEMP_ALARM_MASK \
453e308d 181 (FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
569ff102
HG
182
183/*
184 * Functions declarations
185 */
186
40ac1994
JD
187static int fschmd_probe(struct i2c_client *client,
188 const struct i2c_device_id *id);
189static int fschmd_detect(struct i2c_client *client, int kind,
190 struct i2c_board_info *info);
191static int fschmd_remove(struct i2c_client *client);
569ff102
HG
192static struct fschmd_data *fschmd_update_device(struct device *dev);
193
194/*
195 * Driver data (common to all clients)
196 */
197
40ac1994
JD
198static const struct i2c_device_id fschmd_id[] = {
199 { "fscpos", fscpos },
200 { "fscher", fscher },
201 { "fscscy", fscscy },
202 { "fschrc", fschrc },
203 { "fschmd", fschmd },
204 { }
205};
206MODULE_DEVICE_TABLE(i2c, fschmd_id);
207
569ff102 208static struct i2c_driver fschmd_driver = {
40ac1994 209 .class = I2C_CLASS_HWMON,
569ff102 210 .driver = {
453e308d 211 .name = "fschmd",
569ff102 212 },
40ac1994
JD
213 .probe = fschmd_probe,
214 .remove = fschmd_remove,
215 .id_table = fschmd_id,
216 .detect = fschmd_detect,
217 .address_data = &addr_data,
569ff102
HG
218};
219
220/*
221 * Client data (each client gets its own)
222 */
223
224struct fschmd_data {
97950c3d 225 struct i2c_client *client;
569ff102
HG
226 struct device *hwmon_dev;
227 struct mutex update_lock;
97950c3d
HG
228 struct mutex watchdog_lock;
229 struct list_head list; /* member of the watchdog_data_list */
230 struct kref kref;
231 struct miscdevice watchdog_miscdev;
569ff102 232 int kind;
97950c3d
HG
233 unsigned long watchdog_is_open;
234 char watchdog_expect_close;
235 char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
569ff102
HG
236 char valid; /* zero until following fields are valid */
237 unsigned long last_updated; /* in jiffies */
238
239 /* register values */
97950c3d 240 u8 revision; /* chip revision */
569ff102 241 u8 global_control; /* global control register */
97950c3d
HG
242 u8 watchdog_control; /* watchdog control register */
243 u8 watchdog_state; /* watchdog status register */
244 u8 watchdog_preset; /* watchdog counter preset on trigger val */
569ff102
HG
245 u8 volt[3]; /* 12, 5, battery voltage */
246 u8 temp_act[5]; /* temperature */
247 u8 temp_status[5]; /* status of sensor */
248 u8 temp_max[5]; /* high temp limit, notice: undocumented! */
249 u8 fan_act[6]; /* fans revolutions per second */
250 u8 fan_status[6]; /* fan status */
251 u8 fan_min[6]; /* fan min value for rps */
252 u8 fan_ripple[6]; /* divider for rps */
253};
254
7845cd79 255/* Global variables to hold information read from special DMI tables, which are
97950c3d
HG
256 available on FSC machines with an fscher or later chip. There is no need to
257 protect these with a lock as they are only modified from our attach function
258 which always gets called with the i2c-core lock held and never accessed
259 before the attach function is done with them. */
7845cd79
HG
260static int dmi_mult[3] = { 490, 200, 100 };
261static int dmi_offset[3] = { 0, 0, 0 };
262static int dmi_vref = -1;
263
97950c3d
HG
264/* Somewhat ugly :( global data pointer list with all fschmd devices, so that
265 we can find our device data as when using misc_register there is no other
266 method to get to ones device data from the open fop. */
267static LIST_HEAD(watchdog_data_list);
268/* Note this lock not only protect list access, but also data.kref access */
269static DEFINE_MUTEX(watchdog_data_mutex);
270
271/* Release our data struct when we're detached from the i2c client *and* all
272 references to our watchdog device are released */
273static void fschmd_release_resources(struct kref *ref)
274{
275 struct fschmd_data *data = container_of(ref, struct fschmd_data, kref);
276 kfree(data);
277}
7845cd79 278
569ff102
HG
279/*
280 * Sysfs attr show / store functions
281 */
282
283static ssize_t show_in_value(struct device *dev,
284 struct device_attribute *devattr, char *buf)
285{
286 const int max_reading[3] = { 14200, 6600, 3300 };
287 int index = to_sensor_dev_attr(devattr)->index;
288 struct fschmd_data *data = fschmd_update_device(dev);
289
7845cd79
HG
290 /* fscher / fschrc - 1 as data->kind is an array index, not a chips */
291 if (data->kind == (fscher - 1) || data->kind >= (fschrc - 1))
292 return sprintf(buf, "%d\n", (data->volt[index] * dmi_vref *
293 dmi_mult[index]) / 255 + dmi_offset[index]);
294 else
295 return sprintf(buf, "%d\n", (data->volt[index] *
296 max_reading[index] + 128) / 255);
569ff102
HG
297}
298
299
300#define TEMP_FROM_REG(val) (((val) - 128) * 1000)
301
302static ssize_t show_temp_value(struct device *dev,
303 struct device_attribute *devattr, char *buf)
304{
305 int index = to_sensor_dev_attr(devattr)->index;
306 struct fschmd_data *data = fschmd_update_device(dev);
307
308 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[index]));
309}
310
311static ssize_t show_temp_max(struct device *dev,
312 struct device_attribute *devattr, char *buf)
313{
314 int index = to_sensor_dev_attr(devattr)->index;
315 struct fschmd_data *data = fschmd_update_device(dev);
316
317 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[index]));
318}
319
320static ssize_t store_temp_max(struct device *dev, struct device_attribute
321 *devattr, const char *buf, size_t count)
322{
323 int index = to_sensor_dev_attr(devattr)->index;
324 struct fschmd_data *data = dev_get_drvdata(dev);
325 long v = simple_strtol(buf, NULL, 10) / 1000;
326
327 v = SENSORS_LIMIT(v, -128, 127) + 128;
328
329 mutex_lock(&data->update_lock);
40ac1994 330 i2c_smbus_write_byte_data(to_i2c_client(dev),
569ff102
HG
331 FSCHMD_REG_TEMP_LIMIT[data->kind][index], v);
332 data->temp_max[index] = v;
333 mutex_unlock(&data->update_lock);
334
335 return count;
336}
337
338static ssize_t show_temp_fault(struct device *dev,
339 struct device_attribute *devattr, char *buf)
340{
341 int index = to_sensor_dev_attr(devattr)->index;
342 struct fschmd_data *data = fschmd_update_device(dev);
343
344 /* bit 0 set means sensor working ok, so no fault! */
453e308d 345 if (data->temp_status[index] & FSCHMD_TEMP_WORKING)
569ff102
HG
346 return sprintf(buf, "0\n");
347 else
348 return sprintf(buf, "1\n");
349}
350
351static ssize_t show_temp_alarm(struct device *dev,
352 struct device_attribute *devattr, char *buf)
353{
354 int index = to_sensor_dev_attr(devattr)->index;
355 struct fschmd_data *data = fschmd_update_device(dev);
356
357 if ((data->temp_status[index] & FSCHMD_TEMP_ALARM_MASK) ==
358 FSCHMD_TEMP_ALARM_MASK)
359 return sprintf(buf, "1\n");
360 else
361 return sprintf(buf, "0\n");
362}
363
364
365#define RPM_FROM_REG(val) ((val) * 60)
366
367static ssize_t show_fan_value(struct device *dev,
368 struct device_attribute *devattr, char *buf)
369{
370 int index = to_sensor_dev_attr(devattr)->index;
371 struct fschmd_data *data = fschmd_update_device(dev);
372
373 return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[index]));
374}
375
376static ssize_t show_fan_div(struct device *dev,
377 struct device_attribute *devattr, char *buf)
378{
379 int index = to_sensor_dev_attr(devattr)->index;
380 struct fschmd_data *data = fschmd_update_device(dev);
381
382 /* bits 2..7 reserved => mask with 3 */
383 return sprintf(buf, "%d\n", 1 << (data->fan_ripple[index] & 3));
384}
385
386static ssize_t store_fan_div(struct device *dev, struct device_attribute
387 *devattr, const char *buf, size_t count)
388{
389 u8 reg;
390 int index = to_sensor_dev_attr(devattr)->index;
391 struct fschmd_data *data = dev_get_drvdata(dev);
392 /* supported values: 2, 4, 8 */
393 unsigned long v = simple_strtoul(buf, NULL, 10);
394
395 switch (v) {
396 case 2: v = 1; break;
397 case 4: v = 2; break;
398 case 8: v = 3; break;
399 default:
400 dev_err(dev, "fan_div value %lu not supported. "
401 "Choose one of 2, 4 or 8!\n", v);
402 return -EINVAL;
403 }
404
405 mutex_lock(&data->update_lock);
406
40ac1994 407 reg = i2c_smbus_read_byte_data(to_i2c_client(dev),
569ff102
HG
408 FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
409
410 /* bits 2..7 reserved => mask with 0x03 */
411 reg &= ~0x03;
412 reg |= v;
413
40ac1994 414 i2c_smbus_write_byte_data(to_i2c_client(dev),
569ff102
HG
415 FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg);
416
417 data->fan_ripple[index] = reg;
418
419 mutex_unlock(&data->update_lock);
420
421 return count;
422}
423
424static ssize_t show_fan_alarm(struct device *dev,
425 struct device_attribute *devattr, char *buf)
426{
427 int index = to_sensor_dev_attr(devattr)->index;
428 struct fschmd_data *data = fschmd_update_device(dev);
429
453e308d 430 if (data->fan_status[index] & FSCHMD_FAN_ALARM)
569ff102
HG
431 return sprintf(buf, "1\n");
432 else
433 return sprintf(buf, "0\n");
434}
435
436static ssize_t show_fan_fault(struct device *dev,
437 struct device_attribute *devattr, char *buf)
438{
439 int index = to_sensor_dev_attr(devattr)->index;
440 struct fschmd_data *data = fschmd_update_device(dev);
441
453e308d 442 if (data->fan_status[index] & FSCHMD_FAN_NOT_PRESENT)
569ff102
HG
443 return sprintf(buf, "1\n");
444 else
445 return sprintf(buf, "0\n");
446}
447
448
449static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
450 struct device_attribute *devattr, char *buf)
451{
452 int index = to_sensor_dev_attr(devattr)->index;
453 int val = fschmd_update_device(dev)->fan_min[index];
454
455 /* 0 = allow turning off, 1-255 = 50-100% */
456 if (val)
457 val = val / 2 + 128;
458
459 return sprintf(buf, "%d\n", val);
460}
461
462static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
463 struct device_attribute *devattr, const char *buf, size_t count)
464{
465 int index = to_sensor_dev_attr(devattr)->index;
466 struct fschmd_data *data = dev_get_drvdata(dev);
467 unsigned long v = simple_strtoul(buf, NULL, 10);
468
469 /* register: 0 = allow turning off, 1-255 = 50-100% */
470 if (v) {
471 v = SENSORS_LIMIT(v, 128, 255);
472 v = (v - 128) * 2 + 1;
473 }
474
475 mutex_lock(&data->update_lock);
476
40ac1994 477 i2c_smbus_write_byte_data(to_i2c_client(dev),
569ff102
HG
478 FSCHMD_REG_FAN_MIN[data->kind][index], v);
479 data->fan_min[index] = v;
480
481 mutex_unlock(&data->update_lock);
482
483 return count;
484}
485
486
487/* The FSC hwmon family has the ability to force an attached alert led to flash
488 from software, we export this as an alert_led sysfs attr */
489static ssize_t show_alert_led(struct device *dev,
490 struct device_attribute *devattr, char *buf)
491{
492 struct fschmd_data *data = fschmd_update_device(dev);
493
453e308d 494 if (data->global_control & FSCHMD_CONTROL_ALERT_LED)
569ff102
HG
495 return sprintf(buf, "1\n");
496 else
497 return sprintf(buf, "0\n");
498}
499
500static ssize_t store_alert_led(struct device *dev,
501 struct device_attribute *devattr, const char *buf, size_t count)
502{
503 u8 reg;
504 struct fschmd_data *data = dev_get_drvdata(dev);
505 unsigned long v = simple_strtoul(buf, NULL, 10);
506
507 mutex_lock(&data->update_lock);
508
40ac1994 509 reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
569ff102
HG
510
511 if (v)
453e308d 512 reg |= FSCHMD_CONTROL_ALERT_LED;
569ff102 513 else
453e308d 514 reg &= ~FSCHMD_CONTROL_ALERT_LED;
569ff102 515
40ac1994 516 i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
569ff102
HG
517
518 data->global_control = reg;
519
520 mutex_unlock(&data->update_lock);
521
522 return count;
523}
524
525static struct sensor_device_attribute fschmd_attr[] = {
526 SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
527 SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
528 SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
529 SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0),
530};
531
532static struct sensor_device_attribute fschmd_temp_attr[] = {
533 SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0),
534 SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0),
535 SENSOR_ATTR(temp1_fault, 0444, show_temp_fault, NULL, 0),
536 SENSOR_ATTR(temp1_alarm, 0444, show_temp_alarm, NULL, 0),
537 SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1),
538 SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1),
539 SENSOR_ATTR(temp2_fault, 0444, show_temp_fault, NULL, 1),
540 SENSOR_ATTR(temp2_alarm, 0444, show_temp_alarm, NULL, 1),
541 SENSOR_ATTR(temp3_input, 0444, show_temp_value, NULL, 2),
542 SENSOR_ATTR(temp3_max, 0644, show_temp_max, store_temp_max, 2),
543 SENSOR_ATTR(temp3_fault, 0444, show_temp_fault, NULL, 2),
544 SENSOR_ATTR(temp3_alarm, 0444, show_temp_alarm, NULL, 2),
545 SENSOR_ATTR(temp4_input, 0444, show_temp_value, NULL, 3),
546 SENSOR_ATTR(temp4_max, 0644, show_temp_max, store_temp_max, 3),
547 SENSOR_ATTR(temp4_fault, 0444, show_temp_fault, NULL, 3),
548 SENSOR_ATTR(temp4_alarm, 0444, show_temp_alarm, NULL, 3),
549 SENSOR_ATTR(temp5_input, 0444, show_temp_value, NULL, 4),
550 SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4),
551 SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
552 SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
553};
554
555static struct sensor_device_attribute fschmd_fan_attr[] = {
556 SENSOR_ATTR(fan1_input, 0444, show_fan_value, NULL, 0),
557 SENSOR_ATTR(fan1_div, 0644, show_fan_div, store_fan_div, 0),
558 SENSOR_ATTR(fan1_alarm, 0444, show_fan_alarm, NULL, 0),
559 SENSOR_ATTR(fan1_fault, 0444, show_fan_fault, NULL, 0),
560 SENSOR_ATTR(pwm1_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
561 store_pwm_auto_point1_pwm, 0),
562 SENSOR_ATTR(fan2_input, 0444, show_fan_value, NULL, 1),
563 SENSOR_ATTR(fan2_div, 0644, show_fan_div, store_fan_div, 1),
564 SENSOR_ATTR(fan2_alarm, 0444, show_fan_alarm, NULL, 1),
565 SENSOR_ATTR(fan2_fault, 0444, show_fan_fault, NULL, 1),
566 SENSOR_ATTR(pwm2_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
567 store_pwm_auto_point1_pwm, 1),
568 SENSOR_ATTR(fan3_input, 0444, show_fan_value, NULL, 2),
569 SENSOR_ATTR(fan3_div, 0644, show_fan_div, store_fan_div, 2),
570 SENSOR_ATTR(fan3_alarm, 0444, show_fan_alarm, NULL, 2),
571 SENSOR_ATTR(fan3_fault, 0444, show_fan_fault, NULL, 2),
572 SENSOR_ATTR(pwm3_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
573 store_pwm_auto_point1_pwm, 2),
574 SENSOR_ATTR(fan4_input, 0444, show_fan_value, NULL, 3),
575 SENSOR_ATTR(fan4_div, 0644, show_fan_div, store_fan_div, 3),
576 SENSOR_ATTR(fan4_alarm, 0444, show_fan_alarm, NULL, 3),
577 SENSOR_ATTR(fan4_fault, 0444, show_fan_fault, NULL, 3),
578 SENSOR_ATTR(pwm4_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
579 store_pwm_auto_point1_pwm, 3),
580 SENSOR_ATTR(fan5_input, 0444, show_fan_value, NULL, 4),
581 SENSOR_ATTR(fan5_div, 0644, show_fan_div, store_fan_div, 4),
582 SENSOR_ATTR(fan5_alarm, 0444, show_fan_alarm, NULL, 4),
583 SENSOR_ATTR(fan5_fault, 0444, show_fan_fault, NULL, 4),
584 SENSOR_ATTR(pwm5_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
585 store_pwm_auto_point1_pwm, 4),
586 SENSOR_ATTR(fan6_input, 0444, show_fan_value, NULL, 5),
587 SENSOR_ATTR(fan6_div, 0644, show_fan_div, store_fan_div, 5),
588 SENSOR_ATTR(fan6_alarm, 0444, show_fan_alarm, NULL, 5),
589 SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
590 SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
591 store_pwm_auto_point1_pwm, 5),
592};
593
594
595/*
97950c3d
HG
596 * Watchdog routines
597 */
598
599static int watchdog_set_timeout(struct fschmd_data *data, int timeout)
600{
601 int ret, resolution;
602 int kind = data->kind + 1; /* 0-x array index -> 1-x module param */
603
604 /* 2 second or 60 second resolution? */
605 if (timeout <= 510 || kind == fscpos || kind == fscscy)
606 resolution = 2;
607 else
608 resolution = 60;
609
610 if (timeout < resolution || timeout > (resolution * 255))
611 return -EINVAL;
612
613 mutex_lock(&data->watchdog_lock);
614 if (!data->client) {
615 ret = -ENODEV;
616 goto leave;
617 }
618
619 if (resolution == 2)
620 data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_RESOLUTION;
621 else
622 data->watchdog_control |= FSCHMD_WDOG_CONTROL_RESOLUTION;
623
624 data->watchdog_preset = DIV_ROUND_UP(timeout, resolution);
625
626 /* Write new timeout value */
627 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_PRESET,
628 data->watchdog_preset);
629 /* Write new control register, do not trigger! */
630 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
631 data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER);
632
633 ret = data->watchdog_preset * resolution;
634
635leave:
636 mutex_unlock(&data->watchdog_lock);
637 return ret;
638}
639
640static int watchdog_get_timeout(struct fschmd_data *data)
641{
642 int timeout;
643
644 mutex_lock(&data->watchdog_lock);
645 if (data->watchdog_control & FSCHMD_WDOG_CONTROL_RESOLUTION)
646 timeout = data->watchdog_preset * 60;
647 else
648 timeout = data->watchdog_preset * 2;
649 mutex_unlock(&data->watchdog_lock);
650
651 return timeout;
652}
653
654static int watchdog_trigger(struct fschmd_data *data)
655{
656 int ret = 0;
657
658 mutex_lock(&data->watchdog_lock);
659 if (!data->client) {
660 ret = -ENODEV;
661 goto leave;
662 }
663
664 data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER;
665 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
666 data->watchdog_control);
667leave:
668 mutex_unlock(&data->watchdog_lock);
669 return ret;
670}
671
672static int watchdog_stop(struct fschmd_data *data)
673{
674 int ret = 0;
675
676 mutex_lock(&data->watchdog_lock);
677 if (!data->client) {
678 ret = -ENODEV;
679 goto leave;
680 }
681
682 data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED;
683 /* Don't store the stop flag in our watchdog control register copy, as
684 its a write only bit (read always returns 0) */
685 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL,
686 data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP);
687leave:
688 mutex_unlock(&data->watchdog_lock);
689 return ret;
690}
691
692static int watchdog_open(struct inode *inode, struct file *filp)
693{
694 struct fschmd_data *pos, *data = NULL;
695
696 /* We get called from drivers/char/misc.c with misc_mtx hold, and we
697 call misc_register() from fschmd_probe() with watchdog_data_mutex
698 hold, as misc_register() takes the misc_mtx lock, this is a possible
699 deadlock, so we use mutex_trylock here. */
700 if (!mutex_trylock(&watchdog_data_mutex))
701 return -ERESTARTSYS;
702 list_for_each_entry(pos, &watchdog_data_list, list) {
703 if (pos->watchdog_miscdev.minor == iminor(inode)) {
704 data = pos;
705 break;
706 }
707 }
708 /* Note we can never not have found data, so we don't check for this */
709 kref_get(&data->kref);
710 mutex_unlock(&watchdog_data_mutex);
711
712 if (test_and_set_bit(0, &data->watchdog_is_open))
713 return -EBUSY;
714
715 /* Start the watchdog */
716 watchdog_trigger(data);
717 filp->private_data = data;
718
719 return nonseekable_open(inode, filp);
720}
721
722static int watchdog_release(struct inode *inode, struct file *filp)
723{
724 struct fschmd_data *data = filp->private_data;
725
726 if (data->watchdog_expect_close) {
727 watchdog_stop(data);
728 data->watchdog_expect_close = 0;
729 } else {
730 watchdog_trigger(data);
731 dev_crit(&data->client->dev,
732 "unexpected close, not stopping watchdog!\n");
733 }
734
735 clear_bit(0, &data->watchdog_is_open);
736
737 mutex_lock(&watchdog_data_mutex);
738 kref_put(&data->kref, fschmd_release_resources);
739 mutex_unlock(&watchdog_data_mutex);
740
741 return 0;
742}
743
744static ssize_t watchdog_write(struct file *filp, const char __user *buf,
745 size_t count, loff_t *offset)
746{
747 size_t ret;
748 struct fschmd_data *data = filp->private_data;
749
750 if (count) {
751 if (!nowayout) {
752 size_t i;
753
754 /* Clear it in case it was set with a previous write */
755 data->watchdog_expect_close = 0;
756
757 for (i = 0; i != count; i++) {
758 char c;
759 if (get_user(c, buf + i))
760 return -EFAULT;
761 if (c == 'V')
762 data->watchdog_expect_close = 1;
763 }
764 }
765 ret = watchdog_trigger(data);
766 if (ret < 0)
767 return ret;
768 }
769 return count;
770}
771
772static int watchdog_ioctl(struct inode *inode, struct file *filp,
773 unsigned int cmd, unsigned long arg)
774{
775 static struct watchdog_info ident = {
776 .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT |
777 WDIOF_CARDRESET,
778 .identity = "FSC watchdog"
779 };
780 int i, ret = 0;
781 struct fschmd_data *data = filp->private_data;
782
783 switch (cmd) {
784 case WDIOC_GETSUPPORT:
785 ident.firmware_version = data->revision;
786 if (!nowayout)
787 ident.options |= WDIOF_MAGICCLOSE;
788 if (copy_to_user((void __user *)arg, &ident, sizeof(ident)))
789 ret = -EFAULT;
790 break;
791
792 case WDIOC_GETSTATUS:
793 ret = put_user(0, (int __user *)arg);
794 break;
795
796 case WDIOC_GETBOOTSTATUS:
797 if (data->watchdog_state & FSCHMD_WDOG_STATE_CARDRESET)
798 ret = put_user(WDIOF_CARDRESET, (int __user *)arg);
799 else
800 ret = put_user(0, (int __user *)arg);
801 break;
802
803 case WDIOC_KEEPALIVE:
804 ret = watchdog_trigger(data);
805 break;
806
807 case WDIOC_GETTIMEOUT:
808 i = watchdog_get_timeout(data);
809 ret = put_user(i, (int __user *)arg);
810 break;
811
812 case WDIOC_SETTIMEOUT:
813 if (get_user(i, (int __user *)arg)) {
814 ret = -EFAULT;
815 break;
816 }
817 ret = watchdog_set_timeout(data, i);
818 if (ret > 0)
819 ret = put_user(ret, (int __user *)arg);
820 break;
821
822 case WDIOC_SETOPTIONS:
823 if (get_user(i, (int __user *)arg)) {
824 ret = -EFAULT;
825 break;
826 }
827
828 if (i & WDIOS_DISABLECARD)
829 ret = watchdog_stop(data);
830 else if (i & WDIOS_ENABLECARD)
831 ret = watchdog_trigger(data);
832 else
833 ret = -EINVAL;
834
835 break;
836 default:
837 ret = -ENOTTY;
838 }
839
840 return ret;
841}
842
843static struct file_operations watchdog_fops = {
844 .owner = THIS_MODULE,
845 .llseek = no_llseek,
846 .open = watchdog_open,
847 .release = watchdog_release,
848 .write = watchdog_write,
849 .ioctl = watchdog_ioctl,
850};
851
852
853/*
854 * Detect, register, unregister and update device functions
569ff102
HG
855 */
856
7845cd79
HG
857/* DMI decode routine to read voltage scaling factors from special DMI tables,
858 which are available on FSC machines with an fscher or later chip. */
859static void fschmd_dmi_decode(const struct dmi_header *header)
860{
861 int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
862
863 /* dmi code ugliness, we get passed the address of the contents of
864 a complete DMI record, but in the form of a dmi_header pointer, in
865 reality this address holds header->length bytes of which the header
866 are the first 4 bytes */
867 u8 *dmi_data = (u8 *)header;
868
869 /* We are looking for OEM-specific type 185 */
870 if (header->type != 185)
871 return;
872
873 /* we are looking for what Siemens calls "subtype" 19, the subtype
874 is stored in byte 5 of the dmi block */
875 if (header->length < 5 || dmi_data[4] != 19)
876 return;
877
878 /* After the subtype comes 1 unknown byte and then blocks of 5 bytes,
879 consisting of what Siemens calls an "Entity" number, followed by
880 2 16-bit words in LSB first order */
881 for (i = 6; (i + 4) < header->length; i += 5) {
882 /* entity 1 - 3: voltage multiplier and offset */
883 if (dmi_data[i] >= 1 && dmi_data[i] <= 3) {
884 /* Our in sensors order and the DMI order differ */
885 const int shuffle[3] = { 1, 0, 2 };
886 int in = shuffle[dmi_data[i] - 1];
887
888 /* Check for twice the same entity */
889 if (found & (1 << in))
890 return;
891
892 mult[in] = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
893 offset[in] = dmi_data[i + 3] | (dmi_data[i + 4] << 8);
894
895 found |= 1 << in;
896 }
897
898 /* entity 7: reference voltage */
899 if (dmi_data[i] == 7) {
900 /* Check for twice the same entity */
901 if (found & 0x08)
902 return;
903
904 vref = dmi_data[i + 1] | (dmi_data[i + 2] << 8);
905
906 found |= 0x08;
907 }
908 }
909
910 if (found == 0x0F) {
911 for (i = 0; i < 3; i++) {
912 dmi_mult[i] = mult[i] * 10;
913 dmi_offset[i] = offset[i] * 10;
914 }
915 dmi_vref = vref;
916 }
917}
918
40ac1994
JD
919static int fschmd_detect(struct i2c_client *client, int kind,
920 struct i2c_board_info *info)
569ff102 921{
40ac1994 922 struct i2c_adapter *adapter = client->adapter;
569ff102
HG
923 const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
924 "fschrc", "fschmd" };
569ff102
HG
925
926 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
40ac1994 927 return -ENODEV;
569ff102
HG
928
929 /* Detect & Identify the chip */
930 if (kind <= 0) {
931 char id[4];
932
933 id[0] = i2c_smbus_read_byte_data(client,
934 FSCHMD_REG_IDENT_0);
935 id[1] = i2c_smbus_read_byte_data(client,
936 FSCHMD_REG_IDENT_1);
937 id[2] = i2c_smbus_read_byte_data(client,
938 FSCHMD_REG_IDENT_2);
939 id[3] = '\0';
940
941 if (!strcmp(id, "PEG"))
942 kind = fscpos;
943 else if (!strcmp(id, "HER"))
944 kind = fscher;
945 else if (!strcmp(id, "SCY"))
946 kind = fscscy;
947 else if (!strcmp(id, "HRC"))
948 kind = fschrc;
949 else if (!strcmp(id, "HMD"))
950 kind = fschmd;
951 else
40ac1994 952 return -ENODEV;
569ff102
HG
953 }
954
40ac1994
JD
955 strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE);
956
957 return 0;
958}
959
960static int fschmd_probe(struct i2c_client *client,
961 const struct i2c_device_id *id)
962{
963 struct fschmd_data *data;
40ac1994
JD
964 const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
965 "Heracles", "Heimdall" };
97950c3d 966 const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
40ac1994
JD
967 int i, err;
968 enum chips kind = id->driver_data;
969
970 data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL);
971 if (!data)
972 return -ENOMEM;
973
974 i2c_set_clientdata(client, data);
975 mutex_init(&data->update_lock);
97950c3d
HG
976 mutex_init(&data->watchdog_lock);
977 INIT_LIST_HEAD(&data->list);
978 kref_init(&data->kref);
979 /* Store client pointer in our data struct for watchdog usage
980 (where the client is found through a data ptr instead of the
981 otherway around) */
982 data->client = client;
40ac1994 983
569ff102
HG
984 if (kind == fscpos) {
985 /* The Poseidon has hardwired temp limits, fill these
986 in for the alarm resetting code */
987 data->temp_max[0] = 70 + 128;
988 data->temp_max[1] = 50 + 128;
989 data->temp_max[2] = 50 + 128;
990 }
991
7845cd79 992 /* Read the special DMI table for fscher and newer chips */
453e308d 993 if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) {
7845cd79
HG
994 dmi_walk(fschmd_dmi_decode);
995 if (dmi_vref == -1) {
453e308d
HG
996 dev_warn(&client->dev,
997 "Couldn't get voltage scaling factors from "
7845cd79
HG
998 "BIOS DMI table, using builtin defaults\n");
999 dmi_vref = 33;
1000 }
1001 }
1002
97950c3d
HG
1003 /* Read in some never changing registers */
1004 data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
1005 data->global_control = i2c_smbus_read_byte_data(client,
1006 FSCHMD_REG_CONTROL);
1007 data->watchdog_control = i2c_smbus_read_byte_data(client,
1008 FSCHMD_REG_WDOG_CONTROL);
1009 data->watchdog_state = i2c_smbus_read_byte_data(client,
1010 FSCHMD_REG_WDOG_STATE);
1011 data->watchdog_preset = i2c_smbus_read_byte_data(client,
1012 FSCHMD_REG_WDOG_PRESET);
1013
569ff102
HG
1014 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
1015 data->kind = kind - 1;
569ff102
HG
1016
1017 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
1018 err = device_create_file(&client->dev,
1019 &fschmd_attr[i].dev_attr);
1020 if (err)
1021 goto exit_detach;
1022 }
1023
1024 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++) {
1025 /* Poseidon doesn't have TEMP_LIMIT registers */
1026 if (kind == fscpos && fschmd_temp_attr[i].dev_attr.show ==
1027 show_temp_max)
1028 continue;
1029
1030 err = device_create_file(&client->dev,
1031 &fschmd_temp_attr[i].dev_attr);
1032 if (err)
1033 goto exit_detach;
1034 }
1035
1036 for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++) {
1037 /* Poseidon doesn't have a FAN_MIN register for its 3rd fan */
1038 if (kind == fscpos &&
1039 !strcmp(fschmd_fan_attr[i].dev_attr.attr.name,
1040 "pwm3_auto_point1_pwm"))
1041 continue;
1042
1043 err = device_create_file(&client->dev,
1044 &fschmd_fan_attr[i].dev_attr);
1045 if (err)
1046 goto exit_detach;
1047 }
1048
1049 data->hwmon_dev = hwmon_device_register(&client->dev);
1050 if (IS_ERR(data->hwmon_dev)) {
1051 err = PTR_ERR(data->hwmon_dev);
1052 data->hwmon_dev = NULL;
1053 goto exit_detach;
1054 }
1055
97950c3d
HG
1056 /* We take the data_mutex lock early so that watchdog_open() cannot
1057 run when misc_register() has completed, but we've not yet added
1058 our data to the watchdog_data_list (and set the default timeout) */
1059 mutex_lock(&watchdog_data_mutex);
1060 for (i = 0; i < ARRAY_SIZE(watchdog_minors); i++) {
1061 /* Register our watchdog part */
1062 snprintf(data->watchdog_name, sizeof(data->watchdog_name),
1063 "watchdog%c", (i == 0) ? '\0' : ('0' + i));
1064 data->watchdog_miscdev.name = data->watchdog_name;
1065 data->watchdog_miscdev.fops = &watchdog_fops;
1066 data->watchdog_miscdev.minor = watchdog_minors[i];
1067 err = misc_register(&data->watchdog_miscdev);
1068 if (err == -EBUSY)
1069 continue;
1070 if (err) {
1071 data->watchdog_miscdev.minor = 0;
1072 dev_err(&client->dev,
1073 "Registering watchdog chardev: %d\n", err);
1074 break;
1075 }
1076
1077 list_add(&data->list, &watchdog_data_list);
1078 watchdog_set_timeout(data, 60);
1079 dev_info(&client->dev,
1080 "Registered watchdog chardev major 10, minor: %d\n",
1081 watchdog_minors[i]);
1082 break;
1083 }
1084 if (i == ARRAY_SIZE(watchdog_minors)) {
1085 data->watchdog_miscdev.minor = 0;
1086 dev_warn(&client->dev, "Couldn't register watchdog chardev "
1087 "(due to no free minor)\n");
1088 }
1089 mutex_unlock(&watchdog_data_mutex);
1090
453e308d 1091 dev_info(&client->dev, "Detected FSC %s chip, revision: %d\n",
97950c3d 1092 names[data->kind], (int) data->revision);
569ff102
HG
1093
1094 return 0;
1095
1096exit_detach:
40ac1994 1097 fschmd_remove(client); /* will also free data for us */
569ff102
HG
1098 return err;
1099}
1100
40ac1994 1101static int fschmd_remove(struct i2c_client *client)
569ff102
HG
1102{
1103 struct fschmd_data *data = i2c_get_clientdata(client);
40ac1994 1104 int i;
569ff102 1105
97950c3d
HG
1106 /* Unregister the watchdog (if registered) */
1107 if (data->watchdog_miscdev.minor) {
1108 misc_deregister(&data->watchdog_miscdev);
1109 if (data->watchdog_is_open) {
1110 dev_warn(&client->dev,
1111 "i2c client detached with watchdog open! "
1112 "Stopping watchdog.\n");
1113 watchdog_stop(data);
1114 }
1115 mutex_lock(&watchdog_data_mutex);
1116 list_del(&data->list);
1117 mutex_unlock(&watchdog_data_mutex);
1118 /* Tell the watchdog code the client is gone */
1119 mutex_lock(&data->watchdog_lock);
1120 data->client = NULL;
1121 mutex_unlock(&data->watchdog_lock);
1122 }
1123
569ff102
HG
1124 /* Check if registered in case we're called from fschmd_detect
1125 to cleanup after an error */
1126 if (data->hwmon_dev)
1127 hwmon_device_unregister(data->hwmon_dev);
1128
1129 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++)
1130 device_remove_file(&client->dev, &fschmd_attr[i].dev_attr);
1131 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++)
1132 device_remove_file(&client->dev,
1133 &fschmd_temp_attr[i].dev_attr);
1134 for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++)
1135 device_remove_file(&client->dev,
1136 &fschmd_fan_attr[i].dev_attr);
1137
97950c3d
HG
1138 mutex_lock(&watchdog_data_mutex);
1139 kref_put(&data->kref, fschmd_release_resources);
1140 mutex_unlock(&watchdog_data_mutex);
1141
569ff102
HG
1142 return 0;
1143}
1144
1145static struct fschmd_data *fschmd_update_device(struct device *dev)
1146{
1147 struct i2c_client *client = to_i2c_client(dev);
1148 struct fschmd_data *data = i2c_get_clientdata(client);
1149 int i;
1150
1151 mutex_lock(&data->update_lock);
1152
1153 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
1154
1155 for (i = 0; i < FSCHMD_NO_TEMP_SENSORS[data->kind]; i++) {
1156 data->temp_act[i] = i2c_smbus_read_byte_data(client,
1157 FSCHMD_REG_TEMP_ACT[data->kind][i]);
1158 data->temp_status[i] = i2c_smbus_read_byte_data(client,
1159 FSCHMD_REG_TEMP_STATE[data->kind][i]);
1160
1161 /* The fscpos doesn't have TEMP_LIMIT registers */
1162 if (FSCHMD_REG_TEMP_LIMIT[data->kind][i])
1163 data->temp_max[i] = i2c_smbus_read_byte_data(
1164 client,
1165 FSCHMD_REG_TEMP_LIMIT[data->kind][i]);
1166
1167 /* reset alarm if the alarm condition is gone,
1168 the chip doesn't do this itself */
1169 if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) ==
1170 FSCHMD_TEMP_ALARM_MASK &&
1171 data->temp_act[i] < data->temp_max[i])
1172 i2c_smbus_write_byte_data(client,
1173 FSCHMD_REG_TEMP_STATE[data->kind][i],
453e308d 1174 FSCHMD_TEMP_ALERT);
569ff102
HG
1175 }
1176
1177 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
1178 data->fan_act[i] = i2c_smbus_read_byte_data(client,
1179 FSCHMD_REG_FAN_ACT[data->kind][i]);
1180 data->fan_status[i] = i2c_smbus_read_byte_data(client,
1181 FSCHMD_REG_FAN_STATE[data->kind][i]);
1182 data->fan_ripple[i] = i2c_smbus_read_byte_data(client,
1183 FSCHMD_REG_FAN_RIPPLE[data->kind][i]);
1184
1185 /* The fscpos third fan doesn't have a fan_min */
1186 if (FSCHMD_REG_FAN_MIN[data->kind][i])
1187 data->fan_min[i] = i2c_smbus_read_byte_data(
1188 client,
1189 FSCHMD_REG_FAN_MIN[data->kind][i]);
1190
1191 /* reset fan status if speed is back to > 0 */
453e308d 1192 if ((data->fan_status[i] & FSCHMD_FAN_ALARM) &&
569ff102
HG
1193 data->fan_act[i])
1194 i2c_smbus_write_byte_data(client,
1195 FSCHMD_REG_FAN_STATE[data->kind][i],
453e308d 1196 FSCHMD_FAN_ALARM);
569ff102
HG
1197 }
1198
1199 for (i = 0; i < 3; i++)
1200 data->volt[i] = i2c_smbus_read_byte_data(client,
1201 FSCHMD_REG_VOLT[i]);
1202
569ff102
HG
1203 data->last_updated = jiffies;
1204 data->valid = 1;
1205 }
1206
1207 mutex_unlock(&data->update_lock);
1208
1209 return data;
1210}
1211
1212static int __init fschmd_init(void)
1213{
1214 return i2c_add_driver(&fschmd_driver);
1215}
1216
1217static void __exit fschmd_exit(void)
1218{
1219 i2c_del_driver(&fschmd_driver);
1220}
1221
453e308d 1222MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
569ff102
HG
1223MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
1224 "Heimdall driver");
1225MODULE_LICENSE("GPL");
1226
1227module_init(fschmd_init);
1228module_exit(fschmd_exit);