Chinese: add translation of oops-tracing.txt
[pv_ops_mirror.git] / drivers / hwmon / fschmd.c
blob63a4df0580db78f44fb030056336b699155508a4
1 /* fschmd.c
3 * Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl>
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.
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.
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.
21 * Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes,
22 * Scylla, Heracles and Heimdall chips
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>
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>
45 /* Addresses to scan */
46 static unsigned short normal_i2c[] = { 0x73, I2C_CLIENT_END };
48 /* Insmod parameters */
49 I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
52 * The FSCHMD registers and other defines
55 /* chip identification */
56 #define FSCHMD_REG_IDENT_0 0x00
57 #define FSCHMD_REG_IDENT_1 0x01
58 #define FSCHMD_REG_IDENT_2 0x02
59 #define FSCHMD_REG_REVISION 0x03
61 /* global control and status */
62 #define FSCHMD_REG_EVENT_STATE 0x04
63 #define FSCHMD_REG_CONTROL 0x05
65 #define FSCHMD_CONTROL_ALERT_LED_MASK 0x01
67 /* watchdog (support to be implemented) */
68 #define FSCHMD_REG_WDOG_PRESET 0x28
69 #define FSCHMD_REG_WDOG_STATE 0x23
70 #define FSCHMD_REG_WDOG_CONTROL 0x21
72 /* voltages, weird order is to keep the same order as the old drivers */
73 static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 };
75 /* minimum pwm at which the fan is driven (pwm can by increased depending on
76 the temp. Notice that for the scy some fans share there minimum speed.
77 Also notice that with the scy the sensor order is different then with the
78 other chips, this order was in the 2.4 driver and kept for consistency. */
79 static const u8 FSCHMD_REG_FAN_MIN[5][6] = {
80 { 0x55, 0x65 }, /* pos */
81 { 0x55, 0x65, 0xb5 }, /* her */
82 { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */
83 { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */
84 { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */
87 /* actual fan speed */
88 static const u8 FSCHMD_REG_FAN_ACT[5][6] = {
89 { 0x0e, 0x6b, 0xab }, /* pos */
90 { 0x0e, 0x6b, 0xbb }, /* her */
91 { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */
92 { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */
93 { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */
96 /* fan status registers */
97 static const u8 FSCHMD_REG_FAN_STATE[5][6] = {
98 { 0x0d, 0x62, 0xa2 }, /* pos */
99 { 0x0d, 0x62, 0xb2 }, /* her */
100 { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */
101 { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */
102 { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */
105 /* fan ripple / divider registers */
106 static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = {
107 { 0x0f, 0x6f, 0xaf }, /* pos */
108 { 0x0f, 0x6f, 0xbf }, /* her */
109 { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */
110 { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */
111 { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */
114 static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 };
116 /* Fan status register bitmasks */
117 #define FSCHMD_FAN_ALARM_MASK 0x04 /* called fault by FSC! */
118 #define FSCHMD_FAN_NOT_PRESENT_MASK 0x08 /* not documented */
121 /* actual temperature registers */
122 static const u8 FSCHMD_REG_TEMP_ACT[5][5] = {
123 { 0x64, 0x32, 0x35 }, /* pos */
124 { 0x64, 0x32, 0x35 }, /* her */
125 { 0x64, 0xD0, 0x32, 0x35 }, /* scy */
126 { 0x64, 0x32, 0x35 }, /* hrc */
127 { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */
130 /* temperature state registers */
131 static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
132 { 0x71, 0x81, 0x91 }, /* pos */
133 { 0x71, 0x81, 0x91 }, /* her */
134 { 0x71, 0xd1, 0x81, 0x91 }, /* scy */
135 { 0x71, 0x81, 0x91 }, /* hrc */
136 { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */
139 /* temperature high limit registers, FSC does not document these. Proven to be
140 there with field testing on the fscher and fschrc, already supported / used
141 in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
142 at these addresses, but doesn't want to confirm they are the same as with
143 the fscher?? */
144 static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = {
145 { 0, 0, 0 }, /* pos */
146 { 0x76, 0x86, 0x96 }, /* her */
147 { 0x76, 0xd6, 0x86, 0x96 }, /* scy */
148 { 0x76, 0x86, 0x96 }, /* hrc */
149 { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */
152 /* These were found through experimenting with an fscher, currently they are
153 not used, but we keep them around for future reference.
154 static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 };
155 static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */
157 static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 };
159 /* temp status register bitmasks */
160 #define FSCHMD_TEMP_WORKING_MASK 0x01
161 #define FSCHMD_TEMP_ALERT_MASK 0x02
162 /* there only really is an alarm if the sensor is working and alert == 1 */
163 #define FSCHMD_TEMP_ALARM_MASK \
164 (FSCHMD_TEMP_WORKING_MASK | FSCHMD_TEMP_ALERT_MASK)
166 /* our driver name */
167 #define FSCHMD_NAME "fschmd"
170 * Functions declarations
173 static int fschmd_attach_adapter(struct i2c_adapter *adapter);
174 static int fschmd_detach_client(struct i2c_client *client);
175 static struct fschmd_data *fschmd_update_device(struct device *dev);
178 * Driver data (common to all clients)
181 static struct i2c_driver fschmd_driver = {
182 .driver = {
183 .name = FSCHMD_NAME,
185 .attach_adapter = fschmd_attach_adapter,
186 .detach_client = fschmd_detach_client,
190 * Client data (each client gets its own)
193 struct fschmd_data {
194 struct i2c_client client;
195 struct device *hwmon_dev;
196 struct mutex update_lock;
197 int kind;
198 char valid; /* zero until following fields are valid */
199 unsigned long last_updated; /* in jiffies */
201 /* register values */
202 u8 global_control; /* global control register */
203 u8 volt[3]; /* 12, 5, battery voltage */
204 u8 temp_act[5]; /* temperature */
205 u8 temp_status[5]; /* status of sensor */
206 u8 temp_max[5]; /* high temp limit, notice: undocumented! */
207 u8 fan_act[6]; /* fans revolutions per second */
208 u8 fan_status[6]; /* fan status */
209 u8 fan_min[6]; /* fan min value for rps */
210 u8 fan_ripple[6]; /* divider for rps */
214 * Sysfs attr show / store functions
217 static ssize_t show_in_value(struct device *dev,
218 struct device_attribute *devattr, char *buf)
220 const int max_reading[3] = { 14200, 6600, 3300 };
221 int index = to_sensor_dev_attr(devattr)->index;
222 struct fschmd_data *data = fschmd_update_device(dev);
224 return sprintf(buf, "%d\n", (data->volt[index] *
225 max_reading[index] + 128) / 255);
229 #define TEMP_FROM_REG(val) (((val) - 128) * 1000)
231 static ssize_t show_temp_value(struct device *dev,
232 struct device_attribute *devattr, char *buf)
234 int index = to_sensor_dev_attr(devattr)->index;
235 struct fschmd_data *data = fschmd_update_device(dev);
237 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_act[index]));
240 static ssize_t show_temp_max(struct device *dev,
241 struct device_attribute *devattr, char *buf)
243 int index = to_sensor_dev_attr(devattr)->index;
244 struct fschmd_data *data = fschmd_update_device(dev);
246 return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_max[index]));
249 static ssize_t store_temp_max(struct device *dev, struct device_attribute
250 *devattr, const char *buf, size_t count)
252 int index = to_sensor_dev_attr(devattr)->index;
253 struct fschmd_data *data = dev_get_drvdata(dev);
254 long v = simple_strtol(buf, NULL, 10) / 1000;
256 v = SENSORS_LIMIT(v, -128, 127) + 128;
258 mutex_lock(&data->update_lock);
259 i2c_smbus_write_byte_data(&data->client,
260 FSCHMD_REG_TEMP_LIMIT[data->kind][index], v);
261 data->temp_max[index] = v;
262 mutex_unlock(&data->update_lock);
264 return count;
267 static ssize_t show_temp_fault(struct device *dev,
268 struct device_attribute *devattr, char *buf)
270 int index = to_sensor_dev_attr(devattr)->index;
271 struct fschmd_data *data = fschmd_update_device(dev);
273 /* bit 0 set means sensor working ok, so no fault! */
274 if (data->temp_status[index] & FSCHMD_TEMP_WORKING_MASK)
275 return sprintf(buf, "0\n");
276 else
277 return sprintf(buf, "1\n");
280 static ssize_t show_temp_alarm(struct device *dev,
281 struct device_attribute *devattr, char *buf)
283 int index = to_sensor_dev_attr(devattr)->index;
284 struct fschmd_data *data = fschmd_update_device(dev);
286 if ((data->temp_status[index] & FSCHMD_TEMP_ALARM_MASK) ==
287 FSCHMD_TEMP_ALARM_MASK)
288 return sprintf(buf, "1\n");
289 else
290 return sprintf(buf, "0\n");
294 #define RPM_FROM_REG(val) ((val) * 60)
296 static ssize_t show_fan_value(struct device *dev,
297 struct device_attribute *devattr, char *buf)
299 int index = to_sensor_dev_attr(devattr)->index;
300 struct fschmd_data *data = fschmd_update_device(dev);
302 return sprintf(buf, "%u\n", RPM_FROM_REG(data->fan_act[index]));
305 static ssize_t show_fan_div(struct device *dev,
306 struct device_attribute *devattr, char *buf)
308 int index = to_sensor_dev_attr(devattr)->index;
309 struct fschmd_data *data = fschmd_update_device(dev);
311 /* bits 2..7 reserved => mask with 3 */
312 return sprintf(buf, "%d\n", 1 << (data->fan_ripple[index] & 3));
315 static ssize_t store_fan_div(struct device *dev, struct device_attribute
316 *devattr, const char *buf, size_t count)
318 u8 reg;
319 int index = to_sensor_dev_attr(devattr)->index;
320 struct fschmd_data *data = dev_get_drvdata(dev);
321 /* supported values: 2, 4, 8 */
322 unsigned long v = simple_strtoul(buf, NULL, 10);
324 switch (v) {
325 case 2: v = 1; break;
326 case 4: v = 2; break;
327 case 8: v = 3; break;
328 default:
329 dev_err(dev, "fan_div value %lu not supported. "
330 "Choose one of 2, 4 or 8!\n", v);
331 return -EINVAL;
334 mutex_lock(&data->update_lock);
336 reg = i2c_smbus_read_byte_data(&data->client,
337 FSCHMD_REG_FAN_RIPPLE[data->kind][index]);
339 /* bits 2..7 reserved => mask with 0x03 */
340 reg &= ~0x03;
341 reg |= v;
343 i2c_smbus_write_byte_data(&data->client,
344 FSCHMD_REG_FAN_RIPPLE[data->kind][index], reg);
346 data->fan_ripple[index] = reg;
348 mutex_unlock(&data->update_lock);
350 return count;
353 static ssize_t show_fan_alarm(struct device *dev,
354 struct device_attribute *devattr, char *buf)
356 int index = to_sensor_dev_attr(devattr)->index;
357 struct fschmd_data *data = fschmd_update_device(dev);
359 if (data->fan_status[index] & FSCHMD_FAN_ALARM_MASK)
360 return sprintf(buf, "1\n");
361 else
362 return sprintf(buf, "0\n");
365 static ssize_t show_fan_fault(struct device *dev,
366 struct device_attribute *devattr, char *buf)
368 int index = to_sensor_dev_attr(devattr)->index;
369 struct fschmd_data *data = fschmd_update_device(dev);
371 if (data->fan_status[index] & FSCHMD_FAN_NOT_PRESENT_MASK)
372 return sprintf(buf, "1\n");
373 else
374 return sprintf(buf, "0\n");
378 static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
379 struct device_attribute *devattr, char *buf)
381 int index = to_sensor_dev_attr(devattr)->index;
382 int val = fschmd_update_device(dev)->fan_min[index];
384 /* 0 = allow turning off, 1-255 = 50-100% */
385 if (val)
386 val = val / 2 + 128;
388 return sprintf(buf, "%d\n", val);
391 static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
392 struct device_attribute *devattr, const char *buf, size_t count)
394 int index = to_sensor_dev_attr(devattr)->index;
395 struct fschmd_data *data = dev_get_drvdata(dev);
396 unsigned long v = simple_strtoul(buf, NULL, 10);
398 /* register: 0 = allow turning off, 1-255 = 50-100% */
399 if (v) {
400 v = SENSORS_LIMIT(v, 128, 255);
401 v = (v - 128) * 2 + 1;
404 mutex_lock(&data->update_lock);
406 i2c_smbus_write_byte_data(&data->client,
407 FSCHMD_REG_FAN_MIN[data->kind][index], v);
408 data->fan_min[index] = v;
410 mutex_unlock(&data->update_lock);
412 return count;
416 /* The FSC hwmon family has the ability to force an attached alert led to flash
417 from software, we export this as an alert_led sysfs attr */
418 static ssize_t show_alert_led(struct device *dev,
419 struct device_attribute *devattr, char *buf)
421 struct fschmd_data *data = fschmd_update_device(dev);
423 if (data->global_control & FSCHMD_CONTROL_ALERT_LED_MASK)
424 return sprintf(buf, "1\n");
425 else
426 return sprintf(buf, "0\n");
429 static ssize_t store_alert_led(struct device *dev,
430 struct device_attribute *devattr, const char *buf, size_t count)
432 u8 reg;
433 struct fschmd_data *data = dev_get_drvdata(dev);
434 unsigned long v = simple_strtoul(buf, NULL, 10);
436 mutex_lock(&data->update_lock);
438 reg = i2c_smbus_read_byte_data(&data->client, FSCHMD_REG_CONTROL);
440 if (v)
441 reg |= FSCHMD_CONTROL_ALERT_LED_MASK;
442 else
443 reg &= ~FSCHMD_CONTROL_ALERT_LED_MASK;
445 i2c_smbus_write_byte_data(&data->client, FSCHMD_REG_CONTROL, reg);
447 data->global_control = reg;
449 mutex_unlock(&data->update_lock);
451 return count;
454 static struct sensor_device_attribute fschmd_attr[] = {
455 SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
456 SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
457 SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
458 SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0),
461 static struct sensor_device_attribute fschmd_temp_attr[] = {
462 SENSOR_ATTR(temp1_input, 0444, show_temp_value, NULL, 0),
463 SENSOR_ATTR(temp1_max, 0644, show_temp_max, store_temp_max, 0),
464 SENSOR_ATTR(temp1_fault, 0444, show_temp_fault, NULL, 0),
465 SENSOR_ATTR(temp1_alarm, 0444, show_temp_alarm, NULL, 0),
466 SENSOR_ATTR(temp2_input, 0444, show_temp_value, NULL, 1),
467 SENSOR_ATTR(temp2_max, 0644, show_temp_max, store_temp_max, 1),
468 SENSOR_ATTR(temp2_fault, 0444, show_temp_fault, NULL, 1),
469 SENSOR_ATTR(temp2_alarm, 0444, show_temp_alarm, NULL, 1),
470 SENSOR_ATTR(temp3_input, 0444, show_temp_value, NULL, 2),
471 SENSOR_ATTR(temp3_max, 0644, show_temp_max, store_temp_max, 2),
472 SENSOR_ATTR(temp3_fault, 0444, show_temp_fault, NULL, 2),
473 SENSOR_ATTR(temp3_alarm, 0444, show_temp_alarm, NULL, 2),
474 SENSOR_ATTR(temp4_input, 0444, show_temp_value, NULL, 3),
475 SENSOR_ATTR(temp4_max, 0644, show_temp_max, store_temp_max, 3),
476 SENSOR_ATTR(temp4_fault, 0444, show_temp_fault, NULL, 3),
477 SENSOR_ATTR(temp4_alarm, 0444, show_temp_alarm, NULL, 3),
478 SENSOR_ATTR(temp5_input, 0444, show_temp_value, NULL, 4),
479 SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4),
480 SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
481 SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
484 static struct sensor_device_attribute fschmd_fan_attr[] = {
485 SENSOR_ATTR(fan1_input, 0444, show_fan_value, NULL, 0),
486 SENSOR_ATTR(fan1_div, 0644, show_fan_div, store_fan_div, 0),
487 SENSOR_ATTR(fan1_alarm, 0444, show_fan_alarm, NULL, 0),
488 SENSOR_ATTR(fan1_fault, 0444, show_fan_fault, NULL, 0),
489 SENSOR_ATTR(pwm1_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
490 store_pwm_auto_point1_pwm, 0),
491 SENSOR_ATTR(fan2_input, 0444, show_fan_value, NULL, 1),
492 SENSOR_ATTR(fan2_div, 0644, show_fan_div, store_fan_div, 1),
493 SENSOR_ATTR(fan2_alarm, 0444, show_fan_alarm, NULL, 1),
494 SENSOR_ATTR(fan2_fault, 0444, show_fan_fault, NULL, 1),
495 SENSOR_ATTR(pwm2_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
496 store_pwm_auto_point1_pwm, 1),
497 SENSOR_ATTR(fan3_input, 0444, show_fan_value, NULL, 2),
498 SENSOR_ATTR(fan3_div, 0644, show_fan_div, store_fan_div, 2),
499 SENSOR_ATTR(fan3_alarm, 0444, show_fan_alarm, NULL, 2),
500 SENSOR_ATTR(fan3_fault, 0444, show_fan_fault, NULL, 2),
501 SENSOR_ATTR(pwm3_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
502 store_pwm_auto_point1_pwm, 2),
503 SENSOR_ATTR(fan4_input, 0444, show_fan_value, NULL, 3),
504 SENSOR_ATTR(fan4_div, 0644, show_fan_div, store_fan_div, 3),
505 SENSOR_ATTR(fan4_alarm, 0444, show_fan_alarm, NULL, 3),
506 SENSOR_ATTR(fan4_fault, 0444, show_fan_fault, NULL, 3),
507 SENSOR_ATTR(pwm4_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
508 store_pwm_auto_point1_pwm, 3),
509 SENSOR_ATTR(fan5_input, 0444, show_fan_value, NULL, 4),
510 SENSOR_ATTR(fan5_div, 0644, show_fan_div, store_fan_div, 4),
511 SENSOR_ATTR(fan5_alarm, 0444, show_fan_alarm, NULL, 4),
512 SENSOR_ATTR(fan5_fault, 0444, show_fan_fault, NULL, 4),
513 SENSOR_ATTR(pwm5_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
514 store_pwm_auto_point1_pwm, 4),
515 SENSOR_ATTR(fan6_input, 0444, show_fan_value, NULL, 5),
516 SENSOR_ATTR(fan6_div, 0644, show_fan_div, store_fan_div, 5),
517 SENSOR_ATTR(fan6_alarm, 0444, show_fan_alarm, NULL, 5),
518 SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
519 SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
520 store_pwm_auto_point1_pwm, 5),
525 * Real code
528 static int fschmd_detect(struct i2c_adapter *adapter, int address, int kind)
530 struct i2c_client *client;
531 struct fschmd_data *data;
532 u8 revision;
533 const char * const names[5] = { "Poseidon", "Hermes", "Scylla",
534 "Heracles", "Heimdall" };
535 const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
536 "fschrc", "fschmd" };
537 int i, err = 0;
539 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
540 return 0;
542 /* OK. For now, we presume we have a valid client. We now create the
543 * client structure, even though we cannot fill it completely yet.
544 * But it allows us to access i2c_smbus_read_byte_data. */
545 if (!(data = kzalloc(sizeof(struct fschmd_data), GFP_KERNEL)))
546 return -ENOMEM;
548 client = &data->client;
549 i2c_set_clientdata(client, data);
550 client->addr = address;
551 client->adapter = adapter;
552 client->driver = &fschmd_driver;
553 mutex_init(&data->update_lock);
555 /* Detect & Identify the chip */
556 if (kind <= 0) {
557 char id[4];
559 id[0] = i2c_smbus_read_byte_data(client,
560 FSCHMD_REG_IDENT_0);
561 id[1] = i2c_smbus_read_byte_data(client,
562 FSCHMD_REG_IDENT_1);
563 id[2] = i2c_smbus_read_byte_data(client,
564 FSCHMD_REG_IDENT_2);
565 id[3] = '\0';
567 if (!strcmp(id, "PEG"))
568 kind = fscpos;
569 else if (!strcmp(id, "HER"))
570 kind = fscher;
571 else if (!strcmp(id, "SCY"))
572 kind = fscscy;
573 else if (!strcmp(id, "HRC"))
574 kind = fschrc;
575 else if (!strcmp(id, "HMD"))
576 kind = fschmd;
577 else
578 goto exit_free;
581 if (kind == fscpos) {
582 /* The Poseidon has hardwired temp limits, fill these
583 in for the alarm resetting code */
584 data->temp_max[0] = 70 + 128;
585 data->temp_max[1] = 50 + 128;
586 data->temp_max[2] = 50 + 128;
589 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */
590 data->kind = kind - 1;
591 strlcpy(client->name, client_names[data->kind], I2C_NAME_SIZE);
593 /* Tell the I2C layer a new client has arrived */
594 if ((err = i2c_attach_client(client)))
595 goto exit_free;
597 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) {
598 err = device_create_file(&client->dev,
599 &fschmd_attr[i].dev_attr);
600 if (err)
601 goto exit_detach;
604 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++) {
605 /* Poseidon doesn't have TEMP_LIMIT registers */
606 if (kind == fscpos && fschmd_temp_attr[i].dev_attr.show ==
607 show_temp_max)
608 continue;
610 err = device_create_file(&client->dev,
611 &fschmd_temp_attr[i].dev_attr);
612 if (err)
613 goto exit_detach;
616 for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++) {
617 /* Poseidon doesn't have a FAN_MIN register for its 3rd fan */
618 if (kind == fscpos &&
619 !strcmp(fschmd_fan_attr[i].dev_attr.attr.name,
620 "pwm3_auto_point1_pwm"))
621 continue;
623 err = device_create_file(&client->dev,
624 &fschmd_fan_attr[i].dev_attr);
625 if (err)
626 goto exit_detach;
629 data->hwmon_dev = hwmon_device_register(&client->dev);
630 if (IS_ERR(data->hwmon_dev)) {
631 err = PTR_ERR(data->hwmon_dev);
632 data->hwmon_dev = NULL;
633 goto exit_detach;
636 revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
637 printk(KERN_INFO FSCHMD_NAME ": Detected FSC %s chip, revision: %d\n",
638 names[data->kind], (int) revision);
640 return 0;
642 exit_detach:
643 fschmd_detach_client(client); /* will also free data for us */
644 return err;
646 exit_free:
647 kfree(data);
648 return err;
651 static int fschmd_attach_adapter(struct i2c_adapter *adapter)
653 if (!(adapter->class & I2C_CLASS_HWMON))
654 return 0;
655 return i2c_probe(adapter, &addr_data, fschmd_detect);
658 static int fschmd_detach_client(struct i2c_client *client)
660 struct fschmd_data *data = i2c_get_clientdata(client);
661 int i, err;
663 /* Check if registered in case we're called from fschmd_detect
664 to cleanup after an error */
665 if (data->hwmon_dev)
666 hwmon_device_unregister(data->hwmon_dev);
668 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++)
669 device_remove_file(&client->dev, &fschmd_attr[i].dev_attr);
670 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++)
671 device_remove_file(&client->dev,
672 &fschmd_temp_attr[i].dev_attr);
673 for (i = 0; i < (FSCHMD_NO_FAN_SENSORS[data->kind] * 5); i++)
674 device_remove_file(&client->dev,
675 &fschmd_fan_attr[i].dev_attr);
677 if ((err = i2c_detach_client(client)))
678 return err;
680 kfree(data);
681 return 0;
684 static struct fschmd_data *fschmd_update_device(struct device *dev)
686 struct i2c_client *client = to_i2c_client(dev);
687 struct fschmd_data *data = i2c_get_clientdata(client);
688 int i;
690 mutex_lock(&data->update_lock);
692 if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
694 for (i = 0; i < FSCHMD_NO_TEMP_SENSORS[data->kind]; i++) {
695 data->temp_act[i] = i2c_smbus_read_byte_data(client,
696 FSCHMD_REG_TEMP_ACT[data->kind][i]);
697 data->temp_status[i] = i2c_smbus_read_byte_data(client,
698 FSCHMD_REG_TEMP_STATE[data->kind][i]);
700 /* The fscpos doesn't have TEMP_LIMIT registers */
701 if (FSCHMD_REG_TEMP_LIMIT[data->kind][i])
702 data->temp_max[i] = i2c_smbus_read_byte_data(
703 client,
704 FSCHMD_REG_TEMP_LIMIT[data->kind][i]);
706 /* reset alarm if the alarm condition is gone,
707 the chip doesn't do this itself */
708 if ((data->temp_status[i] & FSCHMD_TEMP_ALARM_MASK) ==
709 FSCHMD_TEMP_ALARM_MASK &&
710 data->temp_act[i] < data->temp_max[i])
711 i2c_smbus_write_byte_data(client,
712 FSCHMD_REG_TEMP_STATE[data->kind][i],
713 FSCHMD_TEMP_ALERT_MASK);
716 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
717 data->fan_act[i] = i2c_smbus_read_byte_data(client,
718 FSCHMD_REG_FAN_ACT[data->kind][i]);
719 data->fan_status[i] = i2c_smbus_read_byte_data(client,
720 FSCHMD_REG_FAN_STATE[data->kind][i]);
721 data->fan_ripple[i] = i2c_smbus_read_byte_data(client,
722 FSCHMD_REG_FAN_RIPPLE[data->kind][i]);
724 /* The fscpos third fan doesn't have a fan_min */
725 if (FSCHMD_REG_FAN_MIN[data->kind][i])
726 data->fan_min[i] = i2c_smbus_read_byte_data(
727 client,
728 FSCHMD_REG_FAN_MIN[data->kind][i]);
730 /* reset fan status if speed is back to > 0 */
731 if ((data->fan_status[i] & FSCHMD_FAN_ALARM_MASK) &&
732 data->fan_act[i])
733 i2c_smbus_write_byte_data(client,
734 FSCHMD_REG_FAN_STATE[data->kind][i],
735 FSCHMD_FAN_ALARM_MASK);
738 for (i = 0; i < 3; i++)
739 data->volt[i] = i2c_smbus_read_byte_data(client,
740 FSCHMD_REG_VOLT[i]);
742 data->global_control = i2c_smbus_read_byte_data(client,
743 FSCHMD_REG_CONTROL);
745 /* To be implemented in the future
746 data->watchdog[0] = i2c_smbus_read_byte_data(client,
747 FSCHMD_REG_WDOG_PRESET);
748 data->watchdog[1] = i2c_smbus_read_byte_data(client,
749 FSCHMD_REG_WDOG_STATE);
750 data->watchdog[2] = i2c_smbus_read_byte_data(client,
751 FSCHMD_REG_WDOG_CONTROL); */
753 data->last_updated = jiffies;
754 data->valid = 1;
757 mutex_unlock(&data->update_lock);
759 return data;
762 static int __init fschmd_init(void)
764 return i2c_add_driver(&fschmd_driver);
767 static void __exit fschmd_exit(void)
769 i2c_del_driver(&fschmd_driver);
772 MODULE_AUTHOR("Hans de Goede <j.w.r.degoede@hhs.nl>");
773 MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and "
774 "Heimdall driver");
775 MODULE_LICENSE("GPL");
777 module_init(fschmd_init);
778 module_exit(fschmd_exit);