blob: d07f4ef750923ca728556ed353ca6eb8ae052873 [file] [log] [blame]
Hans de Goede569ff102007-10-11 08:06:29 -04001/* fschmd.c
2 *
Hans de Goede453e3082009-01-07 16:37:33 +01003 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com>
Hans de Goede569ff102007-10-11 08:06:29 -04004 *
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 Goede97950c32009-01-07 16:37:33 +010045#include <linux/fs.h>
46#include <linux/watchdog.h>
47#include <linux/miscdevice.h>
48#include <linux/uaccess.h>
49#include <linux/kref.h>
Hans de Goede569ff102007-10-11 08:06:29 -040050
51/* Addresses to scan */
Mark M. Hoffman25e9c862008-02-17 22:28:03 -050052static const unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
Hans de Goede569ff102007-10-11 08:06:29 -040053
54/* Insmod parameters */
Hans de Goede97950c32009-01-07 16:37:33 +010055static 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) ")");
Hans de Goede569ff102007-10-11 08:06:29 -040059I2C_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
Hans de Goede453e3082009-01-07 16:37:33 +010075#define FSCHMD_CONTROL_ALERT_LED 0x01
Hans de Goede569ff102007-10-11 08:06:29 -040076
Hans de Goede97950c32009-01-07 16:37:33 +010077/* watchdog */
Hans de Goede569ff102007-10-11 08:06:29 -040078#define FSCHMD_REG_WDOG_PRESET 0x28
79#define FSCHMD_REG_WDOG_STATE 0x23
80#define FSCHMD_REG_WDOG_CONTROL 0x21
81
Hans de Goede97950c32009-01-07 16:37:33 +010082#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
Hans de Goede569ff102007-10-11 08:06:29 -040089/* 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.
Frederik Schwarzer025dfda2008-10-16 19:02:37 +020094 Also notice that with the scy the sensor order is different than with the
Hans de Goede569ff102007-10-11 08:06:29 -040095 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 */
Hans de Goede453e3082009-01-07 16:37:33 +0100134#define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */
135#define FSCHMD_FAN_NOT_PRESENT 0x08 /* not documented */
Hans de Goede569ff102007-10-11 08:06:29 -0400136
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 */
Jean Delvare7dcf9a32007-11-24 17:45:09 -0500153 { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */
Hans de Goede569ff102007-10-11 08:06:29 -0400154};
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 */
Jean Delvare7dcf9a32007-11-24 17:45:09 -0500166 { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */
Hans de Goede569ff102007-10-11 08:06:29 -0400167};
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 */
Hans de Goede453e3082009-01-07 16:37:33 +0100177#define FSCHMD_TEMP_WORKING 0x01
178#define FSCHMD_TEMP_ALERT 0x02
Hans de Goede569ff102007-10-11 08:06:29 -0400179/* there only really is an alarm if the sensor is working and alert == 1 */
180#define FSCHMD_TEMP_ALARM_MASK \
Hans de Goede453e3082009-01-07 16:37:33 +0100181 (FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
Hans de Goede569ff102007-10-11 08:06:29 -0400182
183/*
184 * Functions declarations
185 */
186
Jean Delvare40ac1992008-07-16 19:30:12 +0200187static 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);
Hans de Goede569ff102007-10-11 08:06:29 -0400192static struct fschmd_data *fschmd_update_device(struct device *dev);
193
194/*
195 * Driver data (common to all clients)
196 */
197
Jean Delvare40ac1992008-07-16 19:30:12 +0200198static 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
Hans de Goede569ff102007-10-11 08:06:29 -0400208static struct i2c_driver fschmd_driver = {
Jean Delvare40ac1992008-07-16 19:30:12 +0200209 .class = I2C_CLASS_HWMON,
Hans de Goede569ff102007-10-11 08:06:29 -0400210 .driver = {
Hans de Goede453e3082009-01-07 16:37:33 +0100211 .name = "fschmd",
Hans de Goede569ff102007-10-11 08:06:29 -0400212 },
Jean Delvare40ac1992008-07-16 19:30:12 +0200213 .probe = fschmd_probe,
214 .remove = fschmd_remove,
215 .id_table = fschmd_id,
216 .detect = fschmd_detect,
217 .address_data = &addr_data,
Hans de Goede569ff102007-10-11 08:06:29 -0400218};
219
220/*
221 * Client data (each client gets its own)
222 */
223
224struct fschmd_data {
Hans de Goede97950c32009-01-07 16:37:33 +0100225 struct i2c_client *client;
Hans de Goede569ff102007-10-11 08:06:29 -0400226 struct device *hwmon_dev;
227 struct mutex update_lock;
Hans de Goede97950c32009-01-07 16:37:33 +0100228 struct mutex watchdog_lock;
229 struct list_head list; /* member of the watchdog_data_list */
230 struct kref kref;
231 struct miscdevice watchdog_miscdev;
Hans de Goede569ff102007-10-11 08:06:29 -0400232 int kind;
Hans de Goede97950c32009-01-07 16:37:33 +0100233 unsigned long watchdog_is_open;
234 char watchdog_expect_close;
235 char watchdog_name[10]; /* must be unique to avoid sysfs conflict */
Hans de Goede569ff102007-10-11 08:06:29 -0400236 char valid; /* zero until following fields are valid */
237 unsigned long last_updated; /* in jiffies */
238
239 /* register values */
Hans de Goede97950c32009-01-07 16:37:33 +0100240 u8 revision; /* chip revision */
Hans de Goede569ff102007-10-11 08:06:29 -0400241 u8 global_control; /* global control register */
Hans de Goede97950c32009-01-07 16:37:33 +0100242 u8 watchdog_control; /* watchdog control register */
243 u8 watchdog_state; /* watchdog status register */
244 u8 watchdog_preset; /* watchdog counter preset on trigger val */
Hans de Goede569ff102007-10-11 08:06:29 -0400245 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
Hans de Goede7845cd72007-12-20 16:42:59 +0100255/* Global variables to hold information read from special DMI tables, which are
Hans de Goede97950c32009-01-07 16:37:33 +0100256 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. */
Hans de Goede7845cd72007-12-20 16:42:59 +0100260static int dmi_mult[3] = { 490, 200, 100 };
261static int dmi_offset[3] = { 0, 0, 0 };
262static int dmi_vref = -1;
263
Hans de Goede97950c32009-01-07 16:37:33 +0100264/* 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}
Hans de Goede7845cd72007-12-20 16:42:59 +0100278
Hans de Goede569ff102007-10-11 08:06:29 -0400279/*
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
Hans de Goede7845cd72007-12-20 16:42:59 +0100290 /* 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);
Hans de Goede569ff102007-10-11 08:06:29 -0400297}
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);
Jean Delvare40ac1992008-07-16 19:30:12 +0200330 i2c_smbus_write_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400331 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! */
Hans de Goede453e3082009-01-07 16:37:33 +0100345 if (data->temp_status[index] & FSCHMD_TEMP_WORKING)
Hans de Goede569ff102007-10-11 08:06:29 -0400346 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200407 reg = i2c_smbus_read_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400408 FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
409
410 /* bits 2..7 reserved => mask with 0x03 */
411 reg &= ~0x03;
412 reg |= v;
413
Jean Delvare40ac1992008-07-16 19:30:12 +0200414 i2c_smbus_write_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400415 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
Hans de Goede453e3082009-01-07 16:37:33 +0100430 if (data->fan_status[index] & FSCHMD_FAN_ALARM)
Hans de Goede569ff102007-10-11 08:06:29 -0400431 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
Hans de Goede453e3082009-01-07 16:37:33 +0100442 if (data->fan_status[index] & FSCHMD_FAN_NOT_PRESENT)
Hans de Goede569ff102007-10-11 08:06:29 -0400443 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200477 i2c_smbus_write_byte_data(to_i2c_client(dev),
Hans de Goede569ff102007-10-11 08:06:29 -0400478 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
Hans de Goede453e3082009-01-07 16:37:33 +0100494 if (data->global_control & FSCHMD_CONTROL_ALERT_LED)
Hans de Goede569ff102007-10-11 08:06:29 -0400495 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200509 reg = i2c_smbus_read_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL);
Hans de Goede569ff102007-10-11 08:06:29 -0400510
511 if (v)
Hans de Goede453e3082009-01-07 16:37:33 +0100512 reg |= FSCHMD_CONTROL_ALERT_LED;
Hans de Goede569ff102007-10-11 08:06:29 -0400513 else
Hans de Goede453e3082009-01-07 16:37:33 +0100514 reg &= ~FSCHMD_CONTROL_ALERT_LED;
Hans de Goede569ff102007-10-11 08:06:29 -0400515
Jean Delvare40ac1992008-07-16 19:30:12 +0200516 i2c_smbus_write_byte_data(to_i2c_client(dev), FSCHMD_REG_CONTROL, reg);
Hans de Goede569ff102007-10-11 08:06:29 -0400517
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/*
Hans de Goede97950c32009-01-07 16:37:33 +0100596 * 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
Hans de Goede569ff102007-10-11 08:06:29 -0400855 */
856
Hans de Goede7845cd72007-12-20 16:42:59 +0100857/* 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
Jean Delvare40ac1992008-07-16 19:30:12 +0200919static int fschmd_detect(struct i2c_client *client, int kind,
920 struct i2c_board_info *info)
Hans de Goede569ff102007-10-11 08:06:29 -0400921{
Jean Delvare40ac1992008-07-16 19:30:12 +0200922 struct i2c_adapter *adapter = client->adapter;
Hans de Goede569ff102007-10-11 08:06:29 -0400923 const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
924 "fschrc", "fschmd" };
Hans de Goede569ff102007-10-11 08:06:29 -0400925
926 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
Jean Delvare40ac1992008-07-16 19:30:12 +0200927 return -ENODEV;
Hans de Goede569ff102007-10-11 08:06:29 -0400928
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
Jean Delvare40ac1992008-07-16 19:30:12 +0200952 return -ENODEV;
Hans de Goede569ff102007-10-11 08:06:29 -0400953 }
954
Jean Delvare40ac1992008-07-16 19:30:12 +0200955 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;
Jean Delvare40ac1992008-07-16 19:30:12 +0200964 const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
965 "Heracles", "Heimdall" };
Hans de Goede97950c32009-01-07 16:37:33 +0100966 const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
Jean Delvare40ac1992008-07-16 19:30:12 +0200967 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);
Hans de Goede97950c32009-01-07 16:37:33 +0100976 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;
Jean Delvare40ac1992008-07-16 19:30:12 +0200983
Hans de Goede569ff102007-10-11 08:06:29 -0400984 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
Hans de Goede7845cd72007-12-20 16:42:59 +0100992 /* Read the special DMI table for fscher and newer chips */
Hans de Goede453e3082009-01-07 16:37:33 +0100993 if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) {
Hans de Goede7845cd72007-12-20 16:42:59 +0100994 dmi_walk(fschmd_dmi_decode);
995 if (dmi_vref == -1) {
Hans de Goede453e3082009-01-07 16:37:33 +0100996 dev_warn(&client->dev,
997 "Couldn't get voltage scaling factors from "
Hans de Goede7845cd72007-12-20 16:42:59 +0100998 "BIOS DMI table, using builtin defaults\n");
999 dmi_vref = 33;
1000 }
1001 }
1002
Hans de Goede97950c32009-01-07 16:37:33 +01001003 /* 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
Hans de Goede569ff102007-10-11 08:06:29 -04001014 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
1015 data->kind = kind - 1;
Hans de Goede569ff102007-10-11 08:06:29 -04001016
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
Hans de Goede97950c32009-01-07 16:37:33 +01001056 /* 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
Hans de Goede453e3082009-01-07 16:37:33 +01001091 dev_info(&client->dev, "Detected FSC %s chip, revision: %d\n",
Hans de Goede97950c32009-01-07 16:37:33 +01001092 names[data->kind], (int) data->revision);
Hans de Goede569ff102007-10-11 08:06:29 -04001093
1094 return 0;
1095
1096exit_detach:
Jean Delvare40ac1992008-07-16 19:30:12 +02001097 fschmd_remove(client); /* will also free data for us */
Hans de Goede569ff102007-10-11 08:06:29 -04001098 return err;
1099}
1100
Jean Delvare40ac1992008-07-16 19:30:12 +02001101static int fschmd_remove(struct i2c_client *client)
Hans de Goede569ff102007-10-11 08:06:29 -04001102{
1103 struct fschmd_data *data = i2c_get_clientdata(client);
Jean Delvare40ac1992008-07-16 19:30:12 +02001104 int i;
Hans de Goede569ff102007-10-11 08:06:29 -04001105
Hans de Goede97950c32009-01-07 16:37:33 +01001106 /* 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
Hans de Goede569ff102007-10-11 08:06:29 -04001124 /* 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
Hans de Goede97950c32009-01-07 16:37:33 +01001138 mutex_lock(&watchdog_data_mutex);
1139 kref_put(&data->kref, fschmd_release_resources);
1140 mutex_unlock(&watchdog_data_mutex);
1141
Hans de Goede569ff102007-10-11 08:06:29 -04001142 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],
Hans de Goede453e3082009-01-07 16:37:33 +01001174 FSCHMD_TEMP_ALERT);
Hans de Goede569ff102007-10-11 08:06:29 -04001175 }
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 */
Hans de Goede453e3082009-01-07 16:37:33 +01001192 if ((data->fan_status[i] & FSCHMD_FAN_ALARM) &&
Hans de Goede569ff102007-10-11 08:06:29 -04001193 data->fan_act[i])
1194 i2c_smbus_write_byte_data(client,
1195 FSCHMD_REG_FAN_STATE[data->kind][i],
Hans de Goede453e3082009-01-07 16:37:33 +01001196 FSCHMD_FAN_ALARM);
Hans de Goede569ff102007-10-11 08:06:29 -04001197 }
1198
1199 for (i = 0; i < 3; i++)
1200 data->volt[i] = i2c_smbus_read_byte_data(client,
1201 FSCHMD_REG_VOLT[i]);
1202
Hans de Goede569ff102007-10-11 08:06:29 -04001203 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
Hans de Goede453e3082009-01-07 16:37:33 +01001222MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
Hans de Goede569ff102007-10-11 08:06:29 -04001223MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
1224 "Heimdall driver");
1225MODULE_LICENSE("GPL");
1226
1227module_init(fschmd_init);
1228module_exit(fschmd_exit);