[PATCH] I2C: Separate non-i2c hwmon drivers from i2c-core (4/9)
[linux-2.6-block.git] / drivers / hwmon / w83627ehf.c
CommitLineData
08e7e278
JD
1/*
2 w83627ehf - Driver for the hardware monitoring functionality of
3 the Winbond W83627EHF Super-I/O chip
4 Copyright (C) 2005 Jean Delvare <khali@linux-fr.org>
5
6 Shamelessly ripped from the w83627hf driver
7 Copyright (C) 2003 Mark Studebaker
8
9 Thanks to Leon Moonen, Steve Cliffe and Grant Coady for their help
10 in testing and debugging this driver.
11
8dd2d2ca
JD
12 This driver also supports the W83627EHG, which is the lead-free
13 version of the W83627EHF.
14
08e7e278
JD
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; either version 2 of the License, or
18 (at your option) any later version.
19
20 This program is distributed in the hope that it will be useful,
21 but WITHOUT ANY WARRANTY; without even the implied warranty of
22 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 GNU General Public License for more details.
24
25 You should have received a copy of the GNU General Public License
26 along with this program; if not, write to the Free Software
27 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28
29
30 Supports the following chips:
31
32 Chip #vin #fan #pwm #temp chip_id man_id
33 w83627ehf - 5 - 3 0x88 0x5ca3
34
35 This is a preliminary version of the driver, only supporting the
36 fan and temperature inputs. The chip does much more than that.
37*/
38
39#include <linux/module.h>
40#include <linux/init.h>
41#include <linux/slab.h>
42#include <linux/i2c.h>
fde09509 43#include <linux/i2c-isa.h>
08e7e278 44#include <linux/i2c-sensor.h>
943b0830
MH
45#include <linux/hwmon.h>
46#include <linux/err.h>
08e7e278
JD
47#include <asm/io.h>
48#include "lm75.h"
49
50/* Addresses to scan
51 The actual ISA address is read from Super-I/O configuration space */
52static unsigned short normal_i2c[] = { I2C_CLIENT_END };
53static unsigned int normal_isa[] = { 0, I2C_CLIENT_ISA_END };
54
55/* Insmod parameters */
56SENSORS_INSMOD_1(w83627ehf);
57
58/*
59 * Super-I/O constants and functions
60 */
61
62static int REG; /* The register to read/write */
63static int VAL; /* The value to read/write */
64
65#define W83627EHF_LD_HWM 0x0b
66
67#define SIO_REG_LDSEL 0x07 /* Logical device select */
68#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
69#define SIO_REG_ENABLE 0x30 /* Logical device enable */
70#define SIO_REG_ADDR 0x60 /* Logical device address (2 bytes) */
71
72#define SIO_W83627EHF_ID 0x8840
73#define SIO_ID_MASK 0xFFC0
74
75static inline void
76superio_outb(int reg, int val)
77{
78 outb(reg, REG);
79 outb(val, VAL);
80}
81
82static inline int
83superio_inb(int reg)
84{
85 outb(reg, REG);
86 return inb(VAL);
87}
88
89static inline void
90superio_select(int ld)
91{
92 outb(SIO_REG_LDSEL, REG);
93 outb(ld, VAL);
94}
95
96static inline void
97superio_enter(void)
98{
99 outb(0x87, REG);
100 outb(0x87, REG);
101}
102
103static inline void
104superio_exit(void)
105{
106 outb(0x02, REG);
107 outb(0x02, VAL);
108}
109
110/*
111 * ISA constants
112 */
113
114#define REGION_LENGTH 8
115#define ADDR_REG_OFFSET 5
116#define DATA_REG_OFFSET 6
117
118#define W83627EHF_REG_BANK 0x4E
119#define W83627EHF_REG_CONFIG 0x40
120#define W83627EHF_REG_CHIP_ID 0x49
121#define W83627EHF_REG_MAN_ID 0x4F
122
123static const u16 W83627EHF_REG_FAN[] = { 0x28, 0x29, 0x2a, 0x3f, 0x553 };
124static const u16 W83627EHF_REG_FAN_MIN[] = { 0x3b, 0x3c, 0x3d, 0x3e, 0x55c };
125
126#define W83627EHF_REG_TEMP1 0x27
127#define W83627EHF_REG_TEMP1_HYST 0x3a
128#define W83627EHF_REG_TEMP1_OVER 0x39
129static const u16 W83627EHF_REG_TEMP[] = { 0x150, 0x250 };
130static const u16 W83627EHF_REG_TEMP_HYST[] = { 0x153, 0x253 };
131static const u16 W83627EHF_REG_TEMP_OVER[] = { 0x155, 0x255 };
132static const u16 W83627EHF_REG_TEMP_CONFIG[] = { 0x152, 0x252 };
133
134/* Fan clock dividers are spread over the following five registers */
135#define W83627EHF_REG_FANDIV1 0x47
136#define W83627EHF_REG_FANDIV2 0x4B
137#define W83627EHF_REG_VBAT 0x5D
138#define W83627EHF_REG_DIODE 0x59
139#define W83627EHF_REG_SMI_OVT 0x4C
140
141/*
142 * Conversions
143 */
144
145static inline unsigned int
146fan_from_reg(u8 reg, unsigned int div)
147{
148 if (reg == 0 || reg == 255)
149 return 0;
150 return 1350000U / (reg * div);
151}
152
153static inline unsigned int
154div_from_reg(u8 reg)
155{
156 return 1 << reg;
157}
158
159static inline int
160temp1_from_reg(s8 reg)
161{
162 return reg * 1000;
163}
164
165static inline s8
166temp1_to_reg(int temp)
167{
168 if (temp <= -128000)
169 return -128;
170 if (temp >= 127000)
171 return 127;
172 if (temp < 0)
173 return (temp - 500) / 1000;
174 return (temp + 500) / 1000;
175}
176
177/*
178 * Data structures and manipulation thereof
179 */
180
181struct w83627ehf_data {
182 struct i2c_client client;
943b0830 183 struct class_device *class_dev;
08e7e278
JD
184 struct semaphore lock;
185
186 struct semaphore update_lock;
187 char valid; /* !=0 if following fields are valid */
188 unsigned long last_updated; /* In jiffies */
189
190 /* Register values */
191 u8 fan[5];
192 u8 fan_min[5];
193 u8 fan_div[5];
194 u8 has_fan; /* some fan inputs can be disabled */
195 s8 temp1;
196 s8 temp1_max;
197 s8 temp1_max_hyst;
198 s16 temp[2];
199 s16 temp_max[2];
200 s16 temp_max_hyst[2];
201};
202
203static inline int is_word_sized(u16 reg)
204{
205 return (((reg & 0xff00) == 0x100
206 || (reg & 0xff00) == 0x200)
207 && ((reg & 0x00ff) == 0x50
208 || (reg & 0x00ff) == 0x53
209 || (reg & 0x00ff) == 0x55));
210}
211
212/* We assume that the default bank is 0, thus the following two functions do
213 nothing for registers which live in bank 0. For others, they respectively
214 set the bank register to the correct value (before the register is
215 accessed), and back to 0 (afterwards). */
216static inline void w83627ehf_set_bank(struct i2c_client *client, u16 reg)
217{
218 if (reg & 0xff00) {
219 outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET);
220 outb_p(reg >> 8, client->addr + DATA_REG_OFFSET);
221 }
222}
223
224static inline void w83627ehf_reset_bank(struct i2c_client *client, u16 reg)
225{
226 if (reg & 0xff00) {
227 outb_p(W83627EHF_REG_BANK, client->addr + ADDR_REG_OFFSET);
228 outb_p(0, client->addr + DATA_REG_OFFSET);
229 }
230}
231
232static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg)
233{
234 struct w83627ehf_data *data = i2c_get_clientdata(client);
235 int res, word_sized = is_word_sized(reg);
236
237 down(&data->lock);
238
239 w83627ehf_set_bank(client, reg);
240 outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET);
241 res = inb_p(client->addr + DATA_REG_OFFSET);
242 if (word_sized) {
243 outb_p((reg & 0xff) + 1,
244 client->addr + ADDR_REG_OFFSET);
245 res = (res << 8) + inb_p(client->addr + DATA_REG_OFFSET);
246 }
247 w83627ehf_reset_bank(client, reg);
248
249 up(&data->lock);
250
251 return res;
252}
253
254static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value)
255{
256 struct w83627ehf_data *data = i2c_get_clientdata(client);
257 int word_sized = is_word_sized(reg);
258
259 down(&data->lock);
260
261 w83627ehf_set_bank(client, reg);
262 outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET);
263 if (word_sized) {
264 outb_p(value >> 8, client->addr + DATA_REG_OFFSET);
265 outb_p((reg & 0xff) + 1,
266 client->addr + ADDR_REG_OFFSET);
267 }
268 outb_p(value & 0xff, client->addr + DATA_REG_OFFSET);
269 w83627ehf_reset_bank(client, reg);
270
271 up(&data->lock);
272 return 0;
273}
274
275/* This function assumes that the caller holds data->update_lock */
276static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
277{
278 struct w83627ehf_data *data = i2c_get_clientdata(client);
279 u8 reg;
280
281 switch (nr) {
282 case 0:
283 reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf)
284 | ((data->fan_div[0] & 0x03) << 4);
285 w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
286 reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf)
287 | ((data->fan_div[0] & 0x04) << 3);
288 w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg);
289 break;
290 case 1:
291 reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f)
292 | ((data->fan_div[1] & 0x03) << 6);
293 w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
294 reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf)
295 | ((data->fan_div[1] & 0x04) << 4);
296 w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg);
297 break;
298 case 2:
299 reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV2) & 0x3f)
300 | ((data->fan_div[2] & 0x03) << 6);
301 w83627ehf_write_value(client, W83627EHF_REG_FANDIV2, reg);
302 reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0x7f)
303 | ((data->fan_div[2] & 0x04) << 5);
304 w83627ehf_write_value(client, W83627EHF_REG_VBAT, reg);
305 break;
306 case 3:
307 reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0xfc)
308 | (data->fan_div[3] & 0x03);
309 w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg);
310 reg = (w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT) & 0x7f)
311 | ((data->fan_div[3] & 0x04) << 5);
312 w83627ehf_write_value(client, W83627EHF_REG_SMI_OVT, reg);
313 break;
314 case 4:
315 reg = (w83627ehf_read_value(client, W83627EHF_REG_DIODE) & 0x73)
316 | ((data->fan_div[4] & 0x03) << 3)
317 | ((data->fan_div[4] & 0x04) << 5);
318 w83627ehf_write_value(client, W83627EHF_REG_DIODE, reg);
319 break;
320 }
321}
322
323static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
324{
325 struct i2c_client *client = to_i2c_client(dev);
326 struct w83627ehf_data *data = i2c_get_clientdata(client);
327 int i;
328
329 down(&data->update_lock);
330
331 if (time_after(jiffies, data->last_updated + HZ)
332 || !data->valid) {
333 /* Fan clock dividers */
334 i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
335 data->fan_div[0] = (i >> 4) & 0x03;
336 data->fan_div[1] = (i >> 6) & 0x03;
337 i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV2);
338 data->fan_div[2] = (i >> 6) & 0x03;
339 i = w83627ehf_read_value(client, W83627EHF_REG_VBAT);
340 data->fan_div[0] |= (i >> 3) & 0x04;
341 data->fan_div[1] |= (i >> 4) & 0x04;
342 data->fan_div[2] |= (i >> 5) & 0x04;
343 if (data->has_fan & ((1 << 3) | (1 << 4))) {
344 i = w83627ehf_read_value(client, W83627EHF_REG_DIODE);
345 data->fan_div[3] = i & 0x03;
346 data->fan_div[4] = ((i >> 2) & 0x03)
347 | ((i >> 5) & 0x04);
348 }
349 if (data->has_fan & (1 << 3)) {
350 i = w83627ehf_read_value(client, W83627EHF_REG_SMI_OVT);
351 data->fan_div[3] |= (i >> 5) & 0x04;
352 }
353
354 /* Measured fan speeds and limits */
355 for (i = 0; i < 5; i++) {
356 if (!(data->has_fan & (1 << i)))
357 continue;
358
359 data->fan[i] = w83627ehf_read_value(client,
360 W83627EHF_REG_FAN[i]);
361 data->fan_min[i] = w83627ehf_read_value(client,
362 W83627EHF_REG_FAN_MIN[i]);
363
364 /* If we failed to measure the fan speed and clock
365 divider can be increased, let's try that for next
366 time */
367 if (data->fan[i] == 0xff
368 && data->fan_div[i] < 0x07) {
369 dev_dbg(&client->dev, "Increasing fan %d "
370 "clock divider from %u to %u\n",
371 i, div_from_reg(data->fan_div[i]),
372 div_from_reg(data->fan_div[i] + 1));
373 data->fan_div[i]++;
374 w83627ehf_write_fan_div(client, i);
375 /* Preserve min limit if possible */
376 if (data->fan_min[i] >= 2
377 && data->fan_min[i] != 255)
378 w83627ehf_write_value(client,
379 W83627EHF_REG_FAN_MIN[i],
380 (data->fan_min[i] /= 2));
381 }
382 }
383
384 /* Measured temperatures and limits */
385 data->temp1 = w83627ehf_read_value(client,
386 W83627EHF_REG_TEMP1);
387 data->temp1_max = w83627ehf_read_value(client,
388 W83627EHF_REG_TEMP1_OVER);
389 data->temp1_max_hyst = w83627ehf_read_value(client,
390 W83627EHF_REG_TEMP1_HYST);
391 for (i = 0; i < 2; i++) {
392 data->temp[i] = w83627ehf_read_value(client,
393 W83627EHF_REG_TEMP[i]);
394 data->temp_max[i] = w83627ehf_read_value(client,
395 W83627EHF_REG_TEMP_OVER[i]);
396 data->temp_max_hyst[i] = w83627ehf_read_value(client,
397 W83627EHF_REG_TEMP_HYST[i]);
398 }
399
400 data->last_updated = jiffies;
401 data->valid = 1;
402 }
403
404 up(&data->update_lock);
405 return data;
406}
407
408/*
409 * Sysfs callback functions
410 */
411
412#define show_fan_reg(reg) \
413static ssize_t \
414show_##reg(struct device *dev, char *buf, int nr) \
415{ \
416 struct w83627ehf_data *data = w83627ehf_update_device(dev); \
417 return sprintf(buf, "%d\n", \
418 fan_from_reg(data->reg[nr], \
419 div_from_reg(data->fan_div[nr]))); \
420}
421show_fan_reg(fan);
422show_fan_reg(fan_min);
423
424static ssize_t
425show_fan_div(struct device *dev, char *buf, int nr)
426{
427 struct w83627ehf_data *data = w83627ehf_update_device(dev);
428 return sprintf(buf, "%u\n",
429 div_from_reg(data->fan_div[nr]));
430}
431
432static ssize_t
433store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
434{
435 struct i2c_client *client = to_i2c_client(dev);
436 struct w83627ehf_data *data = i2c_get_clientdata(client);
437 unsigned int val = simple_strtoul(buf, NULL, 10);
438 unsigned int reg;
439 u8 new_div;
440
441 down(&data->update_lock);
442 if (!val) {
443 /* No min limit, alarm disabled */
444 data->fan_min[nr] = 255;
445 new_div = data->fan_div[nr]; /* No change */
446 dev_info(dev, "fan%u low limit and alarm disabled\n", nr + 1);
447 } else if ((reg = 1350000U / val) >= 128 * 255) {
448 /* Speed below this value cannot possibly be represented,
449 even with the highest divider (128) */
450 data->fan_min[nr] = 254;
451 new_div = 7; /* 128 == (1 << 7) */
452 dev_warn(dev, "fan%u low limit %u below minimum %u, set to "
453 "minimum\n", nr + 1, val, fan_from_reg(254, 128));
454 } else if (!reg) {
455 /* Speed above this value cannot possibly be represented,
456 even with the lowest divider (1) */
457 data->fan_min[nr] = 1;
458 new_div = 0; /* 1 == (1 << 0) */
459 dev_warn(dev, "fan%u low limit %u above maximum %u, set to "
b9110b1c 460 "maximum\n", nr + 1, val, fan_from_reg(1, 1));
08e7e278
JD
461 } else {
462 /* Automatically pick the best divider, i.e. the one such
463 that the min limit will correspond to a register value
464 in the 96..192 range */
465 new_div = 0;
466 while (reg > 192 && new_div < 7) {
467 reg >>= 1;
468 new_div++;
469 }
470 data->fan_min[nr] = reg;
471 }
472
473 /* Write both the fan clock divider (if it changed) and the new
474 fan min (unconditionally) */
475 if (new_div != data->fan_div[nr]) {
476 if (new_div > data->fan_div[nr])
477 data->fan[nr] >>= (data->fan_div[nr] - new_div);
478 else
479 data->fan[nr] <<= (new_div - data->fan_div[nr]);
480
481 dev_dbg(dev, "fan%u clock divider changed from %u to %u\n",
482 nr + 1, div_from_reg(data->fan_div[nr]),
483 div_from_reg(new_div));
484 data->fan_div[nr] = new_div;
485 w83627ehf_write_fan_div(client, nr);
486 }
487 w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr],
488 data->fan_min[nr]);
489 up(&data->update_lock);
490
491 return count;
492}
493
494#define sysfs_fan_offset(offset) \
495static ssize_t \
6f637a64
GKH
496show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \
497 char *buf) \
08e7e278
JD
498{ \
499 return show_fan(dev, buf, offset-1); \
500} \
501static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
502 show_reg_fan_##offset, NULL);
503
504#define sysfs_fan_min_offset(offset) \
505static ssize_t \
6f637a64
GKH
506show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
507 char *buf) \
08e7e278
JD
508{ \
509 return show_fan_min(dev, buf, offset-1); \
510} \
511static ssize_t \
6f637a64
GKH
512store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
513 const char *buf, size_t count) \
08e7e278
JD
514{ \
515 return store_fan_min(dev, buf, count, offset-1); \
516} \
517static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
518 show_reg_fan##offset##_min, \
519 store_reg_fan##offset##_min);
520
521#define sysfs_fan_div_offset(offset) \
522static ssize_t \
6f637a64
GKH
523show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \
524 char *buf) \
08e7e278
JD
525{ \
526 return show_fan_div(dev, buf, offset - 1); \
527} \
528static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
529 show_reg_fan##offset##_div, NULL);
530
531sysfs_fan_offset(1);
532sysfs_fan_min_offset(1);
533sysfs_fan_div_offset(1);
534sysfs_fan_offset(2);
535sysfs_fan_min_offset(2);
536sysfs_fan_div_offset(2);
537sysfs_fan_offset(3);
538sysfs_fan_min_offset(3);
539sysfs_fan_div_offset(3);
540sysfs_fan_offset(4);
541sysfs_fan_min_offset(4);
542sysfs_fan_div_offset(4);
543sysfs_fan_offset(5);
544sysfs_fan_min_offset(5);
545sysfs_fan_div_offset(5);
546
547#define show_temp1_reg(reg) \
548static ssize_t \
6f637a64
GKH
549show_##reg(struct device *dev, struct device_attribute *attr, \
550 char *buf) \
08e7e278
JD
551{ \
552 struct w83627ehf_data *data = w83627ehf_update_device(dev); \
553 return sprintf(buf, "%d\n", temp1_from_reg(data->reg)); \
554}
555show_temp1_reg(temp1);
556show_temp1_reg(temp1_max);
557show_temp1_reg(temp1_max_hyst);
558
559#define store_temp1_reg(REG, reg) \
560static ssize_t \
6f637a64
GKH
561store_temp1_##reg(struct device *dev, struct device_attribute *attr, \
562 const char *buf, size_t count) \
08e7e278
JD
563{ \
564 struct i2c_client *client = to_i2c_client(dev); \
565 struct w83627ehf_data *data = i2c_get_clientdata(client); \
566 u32 val = simple_strtoul(buf, NULL, 10); \
567 \
568 down(&data->update_lock); \
569 data->temp1_##reg = temp1_to_reg(val); \
570 w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \
571 data->temp1_##reg); \
572 up(&data->update_lock); \
573 return count; \
574}
575store_temp1_reg(OVER, max);
576store_temp1_reg(HYST, max_hyst);
577
578static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL);
579static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR,
580 show_temp1_max, store_temp1_max);
581static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR,
582 show_temp1_max_hyst, store_temp1_max_hyst);
583
584#define show_temp_reg(reg) \
585static ssize_t \
586show_##reg (struct device *dev, char *buf, int nr) \
587{ \
588 struct w83627ehf_data *data = w83627ehf_update_device(dev); \
589 return sprintf(buf, "%d\n", \
590 LM75_TEMP_FROM_REG(data->reg[nr])); \
591}
592show_temp_reg(temp);
593show_temp_reg(temp_max);
594show_temp_reg(temp_max_hyst);
595
596#define store_temp_reg(REG, reg) \
597static ssize_t \
598store_##reg (struct device *dev, const char *buf, size_t count, int nr) \
599{ \
600 struct i2c_client *client = to_i2c_client(dev); \
601 struct w83627ehf_data *data = i2c_get_clientdata(client); \
602 u32 val = simple_strtoul(buf, NULL, 10); \
603 \
604 down(&data->update_lock); \
605 data->reg[nr] = LM75_TEMP_TO_REG(val); \
606 w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \
607 data->reg[nr]); \
608 up(&data->update_lock); \
609 return count; \
610}
611store_temp_reg(OVER, temp_max);
612store_temp_reg(HYST, temp_max_hyst);
613
614#define sysfs_temp_offset(offset) \
615static ssize_t \
6f637a64
GKH
616show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \
617 char *buf) \
08e7e278
JD
618{ \
619 return show_temp(dev, buf, offset - 2); \
620} \
621static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
622 show_reg_temp##offset, NULL);
623
624#define sysfs_temp_reg_offset(reg, offset) \
625static ssize_t \
6f637a64
GKH
626show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
627 char *buf) \
08e7e278
JD
628{ \
629 return show_temp_##reg(dev, buf, offset - 2); \
630} \
631static ssize_t \
6f637a64
GKH
632store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
633 const char *buf, size_t count) \
08e7e278
JD
634{ \
635 return store_temp_##reg(dev, buf, count, offset - 2); \
636} \
637static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
638 show_reg_temp##offset##_##reg, \
639 store_reg_temp##offset##_##reg);
640
641sysfs_temp_offset(2);
642sysfs_temp_reg_offset(max, 2);
643sysfs_temp_reg_offset(max_hyst, 2);
644sysfs_temp_offset(3);
645sysfs_temp_reg_offset(max, 3);
646sysfs_temp_reg_offset(max_hyst, 3);
647
648/*
649 * Driver and client management
650 */
651
652static struct i2c_driver w83627ehf_driver;
653
654static void w83627ehf_init_client(struct i2c_client *client)
655{
656 int i;
657 u8 tmp;
658
659 /* Start monitoring is needed */
660 tmp = w83627ehf_read_value(client, W83627EHF_REG_CONFIG);
661 if (!(tmp & 0x01))
662 w83627ehf_write_value(client, W83627EHF_REG_CONFIG,
663 tmp | 0x01);
664
665 /* Enable temp2 and temp3 if needed */
666 for (i = 0; i < 2; i++) {
667 tmp = w83627ehf_read_value(client,
668 W83627EHF_REG_TEMP_CONFIG[i]);
669 if (tmp & 0x01)
670 w83627ehf_write_value(client,
671 W83627EHF_REG_TEMP_CONFIG[i],
672 tmp & 0xfe);
673 }
674}
675
676static int w83627ehf_detect(struct i2c_adapter *adapter, int address, int kind)
677{
678 struct i2c_client *client;
679 struct w83627ehf_data *data;
680 int i, err = 0;
681
682 if (!i2c_is_isa_adapter(adapter))
683 return 0;
684
685 if (!request_region(address, REGION_LENGTH, w83627ehf_driver.name)) {
686 err = -EBUSY;
687 goto exit;
688 }
689
690 if (!(data = kmalloc(sizeof(struct w83627ehf_data), GFP_KERNEL))) {
691 err = -ENOMEM;
692 goto exit_release;
693 }
694 memset(data, 0, sizeof(struct w83627ehf_data));
695
696 client = &data->client;
697 i2c_set_clientdata(client, data);
698 client->addr = address;
699 init_MUTEX(&data->lock);
700 client->adapter = adapter;
701 client->driver = &w83627ehf_driver;
702 client->flags = 0;
703
704 strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
705 data->valid = 0;
706 init_MUTEX(&data->update_lock);
707
708 /* Tell the i2c layer a new client has arrived */
709 if ((err = i2c_attach_client(client)))
710 goto exit_free;
711
712 /* Initialize the chip */
713 w83627ehf_init_client(client);
714
715 /* A few vars need to be filled upon startup */
716 for (i = 0; i < 5; i++)
717 data->fan_min[i] = w83627ehf_read_value(client,
718 W83627EHF_REG_FAN_MIN[i]);
719
720 /* It looks like fan4 and fan5 pins can be alternatively used
721 as fan on/off switches */
722 data->has_fan = 0x07; /* fan1, fan2 and fan3 */
723 i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
724 if (i & (1 << 2))
725 data->has_fan |= (1 << 3);
726 if (i & (1 << 0))
727 data->has_fan |= (1 << 4);
728
729 /* Register sysfs hooks */
943b0830
MH
730 data->class_dev = hwmon_device_register(&client->dev);
731 if (IS_ERR(data->class_dev)) {
732 err = PTR_ERR(data->class_dev);
733 goto exit_detach;
734 }
735
08e7e278
JD
736 device_create_file(&client->dev, &dev_attr_fan1_input);
737 device_create_file(&client->dev, &dev_attr_fan1_min);
738 device_create_file(&client->dev, &dev_attr_fan1_div);
739 device_create_file(&client->dev, &dev_attr_fan2_input);
740 device_create_file(&client->dev, &dev_attr_fan2_min);
741 device_create_file(&client->dev, &dev_attr_fan2_div);
742 device_create_file(&client->dev, &dev_attr_fan3_input);
743 device_create_file(&client->dev, &dev_attr_fan3_min);
744 device_create_file(&client->dev, &dev_attr_fan3_div);
745
746 if (data->has_fan & (1 << 3)) {
747 device_create_file(&client->dev, &dev_attr_fan4_input);
748 device_create_file(&client->dev, &dev_attr_fan4_min);
749 device_create_file(&client->dev, &dev_attr_fan4_div);
750 }
751 if (data->has_fan & (1 << 4)) {
752 device_create_file(&client->dev, &dev_attr_fan5_input);
753 device_create_file(&client->dev, &dev_attr_fan5_min);
754 device_create_file(&client->dev, &dev_attr_fan5_div);
755 }
756
757 device_create_file(&client->dev, &dev_attr_temp1_input);
758 device_create_file(&client->dev, &dev_attr_temp1_max);
759 device_create_file(&client->dev, &dev_attr_temp1_max_hyst);
760 device_create_file(&client->dev, &dev_attr_temp2_input);
761 device_create_file(&client->dev, &dev_attr_temp2_max);
762 device_create_file(&client->dev, &dev_attr_temp2_max_hyst);
763 device_create_file(&client->dev, &dev_attr_temp3_input);
764 device_create_file(&client->dev, &dev_attr_temp3_max);
765 device_create_file(&client->dev, &dev_attr_temp3_max_hyst);
766
767 return 0;
768
943b0830
MH
769exit_detach:
770 i2c_detach_client(client);
08e7e278
JD
771exit_free:
772 kfree(data);
773exit_release:
774 release_region(address, REGION_LENGTH);
775exit:
776 return err;
777}
778
779static int w83627ehf_attach_adapter(struct i2c_adapter *adapter)
780{
781 if (!(adapter->class & I2C_CLASS_HWMON))
782 return 0;
783 return i2c_detect(adapter, &addr_data, w83627ehf_detect);
784}
785
786static int w83627ehf_detach_client(struct i2c_client *client)
787{
943b0830 788 struct w83627ehf_data *data = i2c_get_clientdata(client);
08e7e278
JD
789 int err;
790
943b0830
MH
791 hwmon_device_unregister(data->class_dev);
792
08e7e278
JD
793 if ((err = i2c_detach_client(client))) {
794 dev_err(&client->dev, "Client deregistration failed, "
795 "client not detached.\n");
796 return err;
797 }
798 release_region(client->addr, REGION_LENGTH);
943b0830 799 kfree(data);
08e7e278
JD
800
801 return 0;
802}
803
804static struct i2c_driver w83627ehf_driver = {
805 .owner = THIS_MODULE,
806 .name = "w83627ehf",
807 .flags = I2C_DF_NOTIFY,
808 .attach_adapter = w83627ehf_attach_adapter,
809 .detach_client = w83627ehf_detach_client,
810};
811
812static int __init w83627ehf_find(int sioaddr, int *address)
813{
814 u16 val;
815
816 REG = sioaddr;
817 VAL = sioaddr + 1;
818 superio_enter();
819
820 val = (superio_inb(SIO_REG_DEVID) << 8)
821 | superio_inb(SIO_REG_DEVID + 1);
822 if ((val & SIO_ID_MASK) != SIO_W83627EHF_ID) {
823 superio_exit();
824 return -ENODEV;
825 }
826
827 superio_select(W83627EHF_LD_HWM);
828 val = (superio_inb(SIO_REG_ADDR) << 8)
829 | superio_inb(SIO_REG_ADDR + 1);
830 *address = val & ~(REGION_LENGTH - 1);
831 if (*address == 0) {
832 superio_exit();
833 return -ENODEV;
834 }
835
836 /* Activate logical device if needed */
837 val = superio_inb(SIO_REG_ENABLE);
838 if (!(val & 0x01))
839 superio_outb(SIO_REG_ENABLE, val | 0x01);
840
841 superio_exit();
842 return 0;
843}
844
845static int __init sensors_w83627ehf_init(void)
846{
847 if (w83627ehf_find(0x2e, &normal_isa[0])
848 && w83627ehf_find(0x4e, &normal_isa[0]))
849 return -ENODEV;
850
fde09509 851 return i2c_isa_add_driver(&w83627ehf_driver);
08e7e278
JD
852}
853
854static void __exit sensors_w83627ehf_exit(void)
855{
fde09509 856 i2c_isa_del_driver(&w83627ehf_driver);
08e7e278
JD
857}
858
859MODULE_AUTHOR("Jean Delvare <khali@linux-fr.org>");
860MODULE_DESCRIPTION("W83627EHF driver");
861MODULE_LICENSE("GPL");
862
863module_init(sensors_w83627ehf_init);
864module_exit(sensors_w83627ehf_exit);