OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [hwmon/] [lm78.c] - Blame information for rev 78

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
    lm78.c - Part of lm_sensors, Linux kernel modules for hardware
3
             monitoring
4
    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl>
5
    Copyright (c) 2007        Jean Delvare <khali@linux-fr.org>
6
 
7
    This program is free software; you can redistribute it and/or modify
8
    it under the terms of the GNU General Public License as published by
9
    the Free Software Foundation; either version 2 of the License, or
10
    (at your option) any later version.
11
 
12
    This program is distributed in the hope that it will be useful,
13
    but WITHOUT ANY WARRANTY; without even the implied warranty of
14
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
    GNU General Public License for more details.
16
 
17
    You should have received a copy of the GNU General Public License
18
    along with this program; if not, write to the Free Software
19
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
*/
21
 
22
#include <linux/module.h>
23
#include <linux/init.h>
24
#include <linux/slab.h>
25
#include <linux/jiffies.h>
26
#include <linux/i2c.h>
27
#include <linux/platform_device.h>
28
#include <linux/ioport.h>
29
#include <linux/hwmon.h>
30
#include <linux/hwmon-vid.h>
31
#include <linux/hwmon-sysfs.h>
32
#include <linux/err.h>
33
#include <linux/mutex.h>
34
#include <asm/io.h>
35
 
36
/* ISA device, if found */
37
static struct platform_device *pdev;
38
 
39
/* Addresses to scan */
40
static unsigned short normal_i2c[] = { 0x20, 0x21, 0x22, 0x23, 0x24,
41
                                        0x25, 0x26, 0x27, 0x28, 0x29,
42
                                        0x2a, 0x2b, 0x2c, 0x2d, 0x2e,
43
                                        0x2f, I2C_CLIENT_END };
44
static unsigned short isa_address = 0x290;
45
 
46
/* Insmod parameters */
47
I2C_CLIENT_INSMOD_2(lm78, lm79);
48
 
49
/* Many LM78 constants specified below */
50
 
51
/* Length of ISA address segment */
52
#define LM78_EXTENT 8
53
 
54
/* Where are the ISA address/data registers relative to the base address */
55
#define LM78_ADDR_REG_OFFSET 5
56
#define LM78_DATA_REG_OFFSET 6
57
 
58
/* The LM78 registers */
59
#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2)
60
#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2)
61
#define LM78_REG_IN(nr) (0x20 + (nr))
62
 
63
#define LM78_REG_FAN_MIN(nr) (0x3b + (nr))
64
#define LM78_REG_FAN(nr) (0x28 + (nr))
65
 
66
#define LM78_REG_TEMP 0x27
67
#define LM78_REG_TEMP_OVER 0x39
68
#define LM78_REG_TEMP_HYST 0x3a
69
 
70
#define LM78_REG_ALARM1 0x41
71
#define LM78_REG_ALARM2 0x42
72
 
73
#define LM78_REG_VID_FANDIV 0x47
74
 
75
#define LM78_REG_CONFIG 0x40
76
#define LM78_REG_CHIPID 0x49
77
#define LM78_REG_I2C_ADDR 0x48
78
 
79
 
80
/* Conversions. Rounding and limit checking is only done on the TO_REG
81
   variants. */
82
 
83
/* IN: mV, (0V to 4.08V)
84
   REG: 16mV/bit */
85
static inline u8 IN_TO_REG(unsigned long val)
86
{
87
        unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
88
        return (nval + 8) / 16;
89
}
90
#define IN_FROM_REG(val) ((val) *  16)
91
 
92
static inline u8 FAN_TO_REG(long rpm, int div)
93
{
94
        if (rpm <= 0)
95
                return 255;
96
        return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
97
}
98
 
99
static inline int FAN_FROM_REG(u8 val, int div)
100
{
101
        return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
102
}
103
 
104
/* TEMP: mC (-128C to +127C)
105
   REG: 1C/bit, two's complement */
106
static inline s8 TEMP_TO_REG(int val)
107
{
108
        int nval = SENSORS_LIMIT(val, -128000, 127000) ;
109
        return nval<0 ? (nval-500)/1000 : (nval+500)/1000;
110
}
111
 
112
static inline int TEMP_FROM_REG(s8 val)
113
{
114
        return val * 1000;
115
}
116
 
117
#define DIV_FROM_REG(val) (1 << (val))
118
 
119
/* There are some complications in a module like this. First off, LM78 chips
120
   may be both present on the SMBus and the ISA bus, and we have to handle
121
   those cases separately at some places. Second, there might be several
122
   LM78 chips available (well, actually, that is probably never done; but
123
   it is a clean illustration of how to handle a case like that). Finally,
124
   a specific chip may be attached to *both* ISA and SMBus, and we would
125
   not like to detect it double. Fortunately, in the case of the LM78 at
126
   least, a register tells us what SMBus address we are on, so that helps
127
   a bit - except if there could be more than one SMBus. Groan. No solution
128
   for this yet. */
129
 
130
/* For ISA chips, we abuse the i2c_client addr and name fields. We also use
131
   the driver field to differentiate between I2C and ISA chips. */
132
struct lm78_data {
133
        struct i2c_client client;
134
        struct device *hwmon_dev;
135
        struct mutex lock;
136
        enum chips type;
137
 
138
        struct mutex update_lock;
139
        char valid;             /* !=0 if following fields are valid */
140
        unsigned long last_updated;     /* In jiffies */
141
 
142
        u8 in[7];               /* Register value */
143
        u8 in_max[7];           /* Register value */
144
        u8 in_min[7];           /* Register value */
145
        u8 fan[3];              /* Register value */
146
        u8 fan_min[3];          /* Register value */
147
        s8 temp;                /* Register value */
148
        s8 temp_over;           /* Register value */
149
        s8 temp_hyst;           /* Register value */
150
        u8 fan_div[3];          /* Register encoding, shifted right */
151
        u8 vid;                 /* Register encoding, combined */
152
        u16 alarms;             /* Register encoding, combined */
153
};
154
 
155
 
156
static int lm78_attach_adapter(struct i2c_adapter *adapter);
157
static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
158
static int lm78_detach_client(struct i2c_client *client);
159
 
160
static int __devinit lm78_isa_probe(struct platform_device *pdev);
161
static int __devexit lm78_isa_remove(struct platform_device *pdev);
162
 
163
static int lm78_read_value(struct lm78_data *data, u8 reg);
164
static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value);
165
static struct lm78_data *lm78_update_device(struct device *dev);
166
static void lm78_init_device(struct lm78_data *data);
167
 
168
 
169
static struct i2c_driver lm78_driver = {
170
        .driver = {
171
                .name   = "lm78",
172
        },
173
        .id             = I2C_DRIVERID_LM78,
174
        .attach_adapter = lm78_attach_adapter,
175
        .detach_client  = lm78_detach_client,
176
};
177
 
178
static struct platform_driver lm78_isa_driver = {
179
        .driver = {
180
                .owner  = THIS_MODULE,
181
                .name   = "lm78",
182
        },
183
        .probe          = lm78_isa_probe,
184
        .remove         = lm78_isa_remove,
185
};
186
 
187
 
188
/* 7 Voltages */
189
static ssize_t show_in(struct device *dev, struct device_attribute *da,
190
                       char *buf)
191
{
192
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
193
        struct lm78_data *data = lm78_update_device(dev);
194
        return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index]));
195
}
196
 
197
static ssize_t show_in_min(struct device *dev, struct device_attribute *da,
198
                           char *buf)
199
{
200
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
201
        struct lm78_data *data = lm78_update_device(dev);
202
        return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index]));
203
}
204
 
205
static ssize_t show_in_max(struct device *dev, struct device_attribute *da,
206
                           char *buf)
207
{
208
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
209
        struct lm78_data *data = lm78_update_device(dev);
210
        return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index]));
211
}
212
 
213
static ssize_t set_in_min(struct device *dev, struct device_attribute *da,
214
                          const char *buf, size_t count)
215
{
216
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
217
        struct lm78_data *data = dev_get_drvdata(dev);
218
        unsigned long val = simple_strtoul(buf, NULL, 10);
219
        int nr = attr->index;
220
 
221
        mutex_lock(&data->update_lock);
222
        data->in_min[nr] = IN_TO_REG(val);
223
        lm78_write_value(data, LM78_REG_IN_MIN(nr), data->in_min[nr]);
224
        mutex_unlock(&data->update_lock);
225
        return count;
226
}
227
 
228
static ssize_t set_in_max(struct device *dev, struct device_attribute *da,
229
                          const char *buf, size_t count)
230
{
231
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
232
        struct lm78_data *data = dev_get_drvdata(dev);
233
        unsigned long val = simple_strtoul(buf, NULL, 10);
234
        int nr = attr->index;
235
 
236
        mutex_lock(&data->update_lock);
237
        data->in_max[nr] = IN_TO_REG(val);
238
        lm78_write_value(data, LM78_REG_IN_MAX(nr), data->in_max[nr]);
239
        mutex_unlock(&data->update_lock);
240
        return count;
241
}
242
 
243
#define show_in_offset(offset)                                  \
244
static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO,          \
245
                show_in, NULL, offset);                         \
246
static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR,  \
247
                show_in_min, set_in_min, offset);               \
248
static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR,  \
249
                show_in_max, set_in_max, offset);
250
 
251
show_in_offset(0);
252
show_in_offset(1);
253
show_in_offset(2);
254
show_in_offset(3);
255
show_in_offset(4);
256
show_in_offset(5);
257
show_in_offset(6);
258
 
259
/* Temperature */
260
static ssize_t show_temp(struct device *dev, struct device_attribute *da,
261
                         char *buf)
262
{
263
        struct lm78_data *data = lm78_update_device(dev);
264
        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
265
}
266
 
267
static ssize_t show_temp_over(struct device *dev, struct device_attribute *da,
268
                              char *buf)
269
{
270
        struct lm78_data *data = lm78_update_device(dev);
271
        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
272
}
273
 
274
static ssize_t set_temp_over(struct device *dev, struct device_attribute *da,
275
                             const char *buf, size_t count)
276
{
277
        struct lm78_data *data = dev_get_drvdata(dev);
278
        long val = simple_strtol(buf, NULL, 10);
279
 
280
        mutex_lock(&data->update_lock);
281
        data->temp_over = TEMP_TO_REG(val);
282
        lm78_write_value(data, LM78_REG_TEMP_OVER, data->temp_over);
283
        mutex_unlock(&data->update_lock);
284
        return count;
285
}
286
 
287
static ssize_t show_temp_hyst(struct device *dev, struct device_attribute *da,
288
                              char *buf)
289
{
290
        struct lm78_data *data = lm78_update_device(dev);
291
        return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
292
}
293
 
294
static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *da,
295
                             const char *buf, size_t count)
296
{
297
        struct lm78_data *data = dev_get_drvdata(dev);
298
        long val = simple_strtol(buf, NULL, 10);
299
 
300
        mutex_lock(&data->update_lock);
301
        data->temp_hyst = TEMP_TO_REG(val);
302
        lm78_write_value(data, LM78_REG_TEMP_HYST, data->temp_hyst);
303
        mutex_unlock(&data->update_lock);
304
        return count;
305
}
306
 
307
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
308
static DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR,
309
                show_temp_over, set_temp_over);
310
static DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
311
                show_temp_hyst, set_temp_hyst);
312
 
313
/* 3 Fans */
314
static ssize_t show_fan(struct device *dev, struct device_attribute *da,
315
                        char *buf)
316
{
317
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
318
        struct lm78_data *data = lm78_update_device(dev);
319
        int nr = attr->index;
320
        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
321
                DIV_FROM_REG(data->fan_div[nr])) );
322
}
323
 
324
static ssize_t show_fan_min(struct device *dev, struct device_attribute *da,
325
                            char *buf)
326
{
327
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
328
        struct lm78_data *data = lm78_update_device(dev);
329
        int nr = attr->index;
330
        return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
331
                DIV_FROM_REG(data->fan_div[nr])) );
332
}
333
 
334
static ssize_t set_fan_min(struct device *dev, struct device_attribute *da,
335
                           const char *buf, size_t count)
336
{
337
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
338
        struct lm78_data *data = dev_get_drvdata(dev);
339
        int nr = attr->index;
340
        unsigned long val = simple_strtoul(buf, NULL, 10);
341
 
342
        mutex_lock(&data->update_lock);
343
        data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
344
        lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
345
        mutex_unlock(&data->update_lock);
346
        return count;
347
}
348
 
349
static ssize_t show_fan_div(struct device *dev, struct device_attribute *da,
350
                            char *buf)
351
{
352
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
353
        struct lm78_data *data = lm78_update_device(dev);
354
        return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[attr->index]));
355
}
356
 
357
/* Note: we save and restore the fan minimum here, because its value is
358
   determined in part by the fan divisor.  This follows the principle of
359
   least surprise; the user doesn't expect the fan minimum to change just
360
   because the divisor changed. */
361
static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
362
                           const char *buf, size_t count)
363
{
364
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
365
        struct lm78_data *data = dev_get_drvdata(dev);
366
        int nr = attr->index;
367
        unsigned long val = simple_strtoul(buf, NULL, 10);
368
        unsigned long min;
369
        u8 reg;
370
 
371
        mutex_lock(&data->update_lock);
372
        min = FAN_FROM_REG(data->fan_min[nr],
373
                           DIV_FROM_REG(data->fan_div[nr]));
374
 
375
        switch (val) {
376
        case 1: data->fan_div[nr] = 0; break;
377
        case 2: data->fan_div[nr] = 1; break;
378
        case 4: data->fan_div[nr] = 2; break;
379
        case 8: data->fan_div[nr] = 3; break;
380
        default:
381
                dev_err(dev, "fan_div value %ld not "
382
                        "supported. Choose one of 1, 2, 4 or 8!\n", val);
383
                mutex_unlock(&data->update_lock);
384
                return -EINVAL;
385
        }
386
 
387
        reg = lm78_read_value(data, LM78_REG_VID_FANDIV);
388
        switch (nr) {
389
        case 0:
390
                reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
391
                break;
392
        case 1:
393
                reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
394
                break;
395
        }
396
        lm78_write_value(data, LM78_REG_VID_FANDIV, reg);
397
 
398
        data->fan_min[nr] =
399
                FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
400
        lm78_write_value(data, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
401
        mutex_unlock(&data->update_lock);
402
 
403
        return count;
404
}
405
 
406
#define show_fan_offset(offset)                         \
407
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO,         \
408
                show_fan, NULL, offset - 1);                    \
409
static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
410
                show_fan_min, set_fan_min, offset - 1);
411
 
412
show_fan_offset(1);
413
show_fan_offset(2);
414
show_fan_offset(3);
415
 
416
/* Fan 3 divisor is locked in H/W */
417
static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
418
                show_fan_div, set_fan_div, 0);
419
static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
420
                show_fan_div, set_fan_div, 1);
421
static SENSOR_DEVICE_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2);
422
 
423
/* VID */
424
static ssize_t show_vid(struct device *dev, struct device_attribute *da,
425
                        char *buf)
426
{
427
        struct lm78_data *data = lm78_update_device(dev);
428
        return sprintf(buf, "%d\n", vid_from_reg(data->vid, 82));
429
}
430
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
431
 
432
/* Alarms */
433
static ssize_t show_alarms(struct device *dev, struct device_attribute *da,
434
                           char *buf)
435
{
436
        struct lm78_data *data = lm78_update_device(dev);
437
        return sprintf(buf, "%u\n", data->alarms);
438
}
439
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
440
 
441
static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
442
                          char *buf)
443
{
444
        struct lm78_data *data = lm78_update_device(dev);
445
        int nr = to_sensor_dev_attr(da)->index;
446
        return sprintf(buf, "%u\n", (data->alarms >> nr) & 1);
447
}
448
static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0);
449
static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1);
450
static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2);
451
static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3);
452
static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 8);
453
static SENSOR_DEVICE_ATTR(in5_alarm, S_IRUGO, show_alarm, NULL, 9);
454
static SENSOR_DEVICE_ATTR(in6_alarm, S_IRUGO, show_alarm, NULL, 10);
455
static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6);
456
static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
457
static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
458
static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
459
 
460
/* This function is called when:
461
     * lm78_driver is inserted (when this module is loaded), for each
462
       available adapter
463
     * when a new adapter is inserted (and lm78_driver is still present) */
464
static int lm78_attach_adapter(struct i2c_adapter *adapter)
465
{
466
        if (!(adapter->class & I2C_CLASS_HWMON))
467
                return 0;
468
        return i2c_probe(adapter, &addr_data, lm78_detect);
469
}
470
 
471
static struct attribute *lm78_attributes[] = {
472
        &sensor_dev_attr_in0_input.dev_attr.attr,
473
        &sensor_dev_attr_in0_min.dev_attr.attr,
474
        &sensor_dev_attr_in0_max.dev_attr.attr,
475
        &sensor_dev_attr_in0_alarm.dev_attr.attr,
476
        &sensor_dev_attr_in1_input.dev_attr.attr,
477
        &sensor_dev_attr_in1_min.dev_attr.attr,
478
        &sensor_dev_attr_in1_max.dev_attr.attr,
479
        &sensor_dev_attr_in1_alarm.dev_attr.attr,
480
        &sensor_dev_attr_in2_input.dev_attr.attr,
481
        &sensor_dev_attr_in2_min.dev_attr.attr,
482
        &sensor_dev_attr_in2_max.dev_attr.attr,
483
        &sensor_dev_attr_in2_alarm.dev_attr.attr,
484
        &sensor_dev_attr_in3_input.dev_attr.attr,
485
        &sensor_dev_attr_in3_min.dev_attr.attr,
486
        &sensor_dev_attr_in3_max.dev_attr.attr,
487
        &sensor_dev_attr_in3_alarm.dev_attr.attr,
488
        &sensor_dev_attr_in4_input.dev_attr.attr,
489
        &sensor_dev_attr_in4_min.dev_attr.attr,
490
        &sensor_dev_attr_in4_max.dev_attr.attr,
491
        &sensor_dev_attr_in4_alarm.dev_attr.attr,
492
        &sensor_dev_attr_in5_input.dev_attr.attr,
493
        &sensor_dev_attr_in5_min.dev_attr.attr,
494
        &sensor_dev_attr_in5_max.dev_attr.attr,
495
        &sensor_dev_attr_in5_alarm.dev_attr.attr,
496
        &sensor_dev_attr_in6_input.dev_attr.attr,
497
        &sensor_dev_attr_in6_min.dev_attr.attr,
498
        &sensor_dev_attr_in6_max.dev_attr.attr,
499
        &sensor_dev_attr_in6_alarm.dev_attr.attr,
500
        &dev_attr_temp1_input.attr,
501
        &dev_attr_temp1_max.attr,
502
        &dev_attr_temp1_max_hyst.attr,
503
        &sensor_dev_attr_temp1_alarm.dev_attr.attr,
504
        &sensor_dev_attr_fan1_input.dev_attr.attr,
505
        &sensor_dev_attr_fan1_min.dev_attr.attr,
506
        &sensor_dev_attr_fan1_div.dev_attr.attr,
507
        &sensor_dev_attr_fan1_alarm.dev_attr.attr,
508
        &sensor_dev_attr_fan2_input.dev_attr.attr,
509
        &sensor_dev_attr_fan2_min.dev_attr.attr,
510
        &sensor_dev_attr_fan2_div.dev_attr.attr,
511
        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
512
        &sensor_dev_attr_fan3_input.dev_attr.attr,
513
        &sensor_dev_attr_fan3_min.dev_attr.attr,
514
        &sensor_dev_attr_fan3_div.dev_attr.attr,
515
        &sensor_dev_attr_fan3_alarm.dev_attr.attr,
516
        &dev_attr_alarms.attr,
517
        &dev_attr_cpu0_vid.attr,
518
 
519
        NULL
520
};
521
 
522
static const struct attribute_group lm78_group = {
523
        .attrs = lm78_attributes,
524
};
525
 
526
/* I2C devices get this name attribute automatically, but for ISA devices
527
   we must create it by ourselves. */
528
static ssize_t show_name(struct device *dev, struct device_attribute
529
                         *devattr, char *buf)
530
{
531
        struct lm78_data *data = dev_get_drvdata(dev);
532
 
533
        return sprintf(buf, "%s\n", data->client.name);
534
}
535
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
536
 
537
/* This function is called by i2c_probe */
538
static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
539
{
540
        int i, err;
541
        struct i2c_client *new_client;
542
        struct lm78_data *data;
543
        const char *client_name = "";
544
 
545
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
546
                err = -ENODEV;
547
                goto ERROR1;
548
        }
549
 
550
        /* OK. For now, we presume we have a valid client. We now create the
551
           client structure, even though we cannot fill it completely yet.
552
           But it allows us to access lm78_{read,write}_value. */
553
 
554
        if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
555
                err = -ENOMEM;
556
                goto ERROR1;
557
        }
558
 
559
        new_client = &data->client;
560
        i2c_set_clientdata(new_client, data);
561
        new_client->addr = address;
562
        new_client->adapter = adapter;
563
        new_client->driver = &lm78_driver;
564
 
565
        /* Now, we do the remaining detection. */
566
        if (kind < 0) {
567
                if (lm78_read_value(data, LM78_REG_CONFIG) & 0x80) {
568
                        err = -ENODEV;
569
                        goto ERROR2;
570
                }
571
                if (lm78_read_value(data, LM78_REG_I2C_ADDR) !=
572
                    address) {
573
                        err = -ENODEV;
574
                        goto ERROR2;
575
                }
576
        }
577
 
578
        /* Determine the chip type. */
579
        if (kind <= 0) {
580
                i = lm78_read_value(data, LM78_REG_CHIPID);
581
                if (i == 0x00 || i == 0x20      /* LM78 */
582
                 || i == 0x40)                  /* LM78-J */
583
                        kind = lm78;
584
                else if ((i & 0xfe) == 0xc0)
585
                        kind = lm79;
586
                else {
587
                        if (kind == 0)
588
                                dev_warn(&adapter->dev, "Ignoring 'force' "
589
                                        "parameter for unknown chip at "
590
                                        "adapter %d, address 0x%02x\n",
591
                                        i2c_adapter_id(adapter), address);
592
                        err = -ENODEV;
593
                        goto ERROR2;
594
                }
595
        }
596
 
597
        if (kind == lm78) {
598
                client_name = "lm78";
599
        } else if (kind == lm79) {
600
                client_name = "lm79";
601
        }
602
 
603
        /* Fill in the remaining client fields and put into the global list */
604
        strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
605
        data->type = kind;
606
 
607
        /* Tell the I2C layer a new client has arrived */
608
        if ((err = i2c_attach_client(new_client)))
609
                goto ERROR2;
610
 
611
        /* Initialize the LM78 chip */
612
        lm78_init_device(data);
613
 
614
        /* Register sysfs hooks */
615
        if ((err = sysfs_create_group(&new_client->dev.kobj, &lm78_group)))
616
                goto ERROR3;
617
 
618
        data->hwmon_dev = hwmon_device_register(&new_client->dev);
619
        if (IS_ERR(data->hwmon_dev)) {
620
                err = PTR_ERR(data->hwmon_dev);
621
                goto ERROR4;
622
        }
623
 
624
        return 0;
625
 
626
ERROR4:
627
        sysfs_remove_group(&new_client->dev.kobj, &lm78_group);
628
ERROR3:
629
        i2c_detach_client(new_client);
630
ERROR2:
631
        kfree(data);
632
ERROR1:
633
        return err;
634
}
635
 
636
static int lm78_detach_client(struct i2c_client *client)
637
{
638
        struct lm78_data *data = i2c_get_clientdata(client);
639
        int err;
640
 
641
        hwmon_device_unregister(data->hwmon_dev);
642
        sysfs_remove_group(&client->dev.kobj, &lm78_group);
643
 
644
        if ((err = i2c_detach_client(client)))
645
                return err;
646
 
647
        kfree(data);
648
 
649
        return 0;
650
}
651
 
652
static int __devinit lm78_isa_probe(struct platform_device *pdev)
653
{
654
        int err;
655
        struct lm78_data *data;
656
        struct resource *res;
657
        const char *name;
658
 
659
        /* Reserve the ISA region */
660
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
661
        if (!request_region(res->start, LM78_EXTENT, "lm78")) {
662
                err = -EBUSY;
663
                goto exit;
664
        }
665
 
666
        if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
667
                err = -ENOMEM;
668
                goto exit_release_region;
669
        }
670
        mutex_init(&data->lock);
671
        data->client.addr = res->start;
672
        i2c_set_clientdata(&data->client, data);
673
        platform_set_drvdata(pdev, data);
674
 
675
        if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
676
                data->type = lm79;
677
                name = "lm79";
678
        } else {
679
                data->type = lm78;
680
                name = "lm78";
681
        }
682
        strlcpy(data->client.name, name, I2C_NAME_SIZE);
683
 
684
        /* Initialize the LM78 chip */
685
        lm78_init_device(data);
686
 
687
        /* Register sysfs hooks */
688
        if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
689
         || (err = device_create_file(&pdev->dev, &dev_attr_name)))
690
                goto exit_remove_files;
691
 
692
        data->hwmon_dev = hwmon_device_register(&pdev->dev);
693
        if (IS_ERR(data->hwmon_dev)) {
694
                err = PTR_ERR(data->hwmon_dev);
695
                goto exit_remove_files;
696
        }
697
 
698
        return 0;
699
 
700
 exit_remove_files:
701
        sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
702
        device_remove_file(&pdev->dev, &dev_attr_name);
703
        kfree(data);
704
 exit_release_region:
705
        release_region(res->start, LM78_EXTENT);
706
 exit:
707
        return err;
708
}
709
 
710
static int __devexit lm78_isa_remove(struct platform_device *pdev)
711
{
712
        struct lm78_data *data = platform_get_drvdata(pdev);
713
 
714
        hwmon_device_unregister(data->hwmon_dev);
715
        sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
716
        device_remove_file(&pdev->dev, &dev_attr_name);
717
        release_region(data->client.addr, LM78_EXTENT);
718
        kfree(data);
719
 
720
        return 0;
721
}
722
 
723
/* The SMBus locks itself, but ISA access must be locked explicitly!
724
   We don't want to lock the whole ISA bus, so we lock each client
725
   separately.
726
   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
727
   would slow down the LM78 access and should not be necessary.  */
728
static int lm78_read_value(struct lm78_data *data, u8 reg)
729
{
730
        struct i2c_client *client = &data->client;
731
 
732
        if (!client->driver) { /* ISA device */
733
                int res;
734
                mutex_lock(&data->lock);
735
                outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
736
                res = inb_p(client->addr + LM78_DATA_REG_OFFSET);
737
                mutex_unlock(&data->lock);
738
                return res;
739
        } else
740
                return i2c_smbus_read_byte_data(client, reg);
741
}
742
 
743
/* The SMBus locks itself, but ISA access muse be locked explicitly!
744
   We don't want to lock the whole ISA bus, so we lock each client
745
   separately.
746
   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
747
   would slow down the LM78 access and should not be necessary.
748
   There are some ugly typecasts here, but the good new is - they should
749
   nowhere else be necessary! */
750
static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value)
751
{
752
        struct i2c_client *client = &data->client;
753
 
754
        if (!client->driver) { /* ISA device */
755
                mutex_lock(&data->lock);
756
                outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
757
                outb_p(value, client->addr + LM78_DATA_REG_OFFSET);
758
                mutex_unlock(&data->lock);
759
                return 0;
760
        } else
761
                return i2c_smbus_write_byte_data(client, reg, value);
762
}
763
 
764
static void lm78_init_device(struct lm78_data *data)
765
{
766
        u8 config;
767
        int i;
768
 
769
        /* Start monitoring */
770
        config = lm78_read_value(data, LM78_REG_CONFIG);
771
        if ((config & 0x09) != 0x01)
772
                lm78_write_value(data, LM78_REG_CONFIG,
773
                                 (config & 0xf7) | 0x01);
774
 
775
        /* A few vars need to be filled upon startup */
776
        for (i = 0; i < 3; i++) {
777
                data->fan_min[i] = lm78_read_value(data,
778
                                        LM78_REG_FAN_MIN(i));
779
        }
780
 
781
        mutex_init(&data->update_lock);
782
}
783
 
784
static struct lm78_data *lm78_update_device(struct device *dev)
785
{
786
        struct lm78_data *data = dev_get_drvdata(dev);
787
        int i;
788
 
789
        mutex_lock(&data->update_lock);
790
 
791
        if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
792
            || !data->valid) {
793
 
794
                dev_dbg(dev, "Starting lm78 update\n");
795
 
796
                for (i = 0; i <= 6; i++) {
797
                        data->in[i] =
798
                            lm78_read_value(data, LM78_REG_IN(i));
799
                        data->in_min[i] =
800
                            lm78_read_value(data, LM78_REG_IN_MIN(i));
801
                        data->in_max[i] =
802
                            lm78_read_value(data, LM78_REG_IN_MAX(i));
803
                }
804
                for (i = 0; i < 3; i++) {
805
                        data->fan[i] =
806
                            lm78_read_value(data, LM78_REG_FAN(i));
807
                        data->fan_min[i] =
808
                            lm78_read_value(data, LM78_REG_FAN_MIN(i));
809
                }
810
                data->temp = lm78_read_value(data, LM78_REG_TEMP);
811
                data->temp_over =
812
                    lm78_read_value(data, LM78_REG_TEMP_OVER);
813
                data->temp_hyst =
814
                    lm78_read_value(data, LM78_REG_TEMP_HYST);
815
                i = lm78_read_value(data, LM78_REG_VID_FANDIV);
816
                data->vid = i & 0x0f;
817
                if (data->type == lm79)
818
                        data->vid |=
819
                            (lm78_read_value(data, LM78_REG_CHIPID) &
820
                             0x01) << 4;
821
                else
822
                        data->vid |= 0x10;
823
                data->fan_div[0] = (i >> 4) & 0x03;
824
                data->fan_div[1] = i >> 6;
825
                data->alarms = lm78_read_value(data, LM78_REG_ALARM1) +
826
                    (lm78_read_value(data, LM78_REG_ALARM2) << 8);
827
                data->last_updated = jiffies;
828
                data->valid = 1;
829
 
830
                data->fan_div[2] = 1;
831
        }
832
 
833
        mutex_unlock(&data->update_lock);
834
 
835
        return data;
836
}
837
 
838
/* return 1 if a supported chip is found, 0 otherwise */
839
static int __init lm78_isa_found(unsigned short address)
840
{
841
        int val, save, found = 0;
842
 
843
        if (!request_region(address, LM78_EXTENT, "lm78"))
844
                return 0;
845
 
846
#define REALLY_SLOW_IO
847
        /* We need the timeouts for at least some LM78-like
848
           chips. But only if we read 'undefined' registers. */
849
        val = inb_p(address + 1);
850
        if (inb_p(address + 2) != val
851
         || inb_p(address + 3) != val
852
         || inb_p(address + 7) != val)
853
                goto release;
854
#undef REALLY_SLOW_IO
855
 
856
        /* We should be able to change the 7 LSB of the address port. The
857
           MSB (busy flag) should be clear initially, set after the write. */
858
        save = inb_p(address + LM78_ADDR_REG_OFFSET);
859
        if (save & 0x80)
860
                goto release;
861
        val = ~save & 0x7f;
862
        outb_p(val, address + LM78_ADDR_REG_OFFSET);
863
        if (inb_p(address + LM78_ADDR_REG_OFFSET) != (val | 0x80)) {
864
                outb_p(save, address + LM78_ADDR_REG_OFFSET);
865
                goto release;
866
        }
867
 
868
        /* We found a device, now see if it could be an LM78 */
869
        outb_p(LM78_REG_CONFIG, address + LM78_ADDR_REG_OFFSET);
870
        val = inb_p(address + LM78_DATA_REG_OFFSET);
871
        if (val & 0x80)
872
                goto release;
873
        outb_p(LM78_REG_I2C_ADDR, address + LM78_ADDR_REG_OFFSET);
874
        val = inb_p(address + LM78_DATA_REG_OFFSET);
875
        if (val < 0x03 || val > 0x77)   /* Not a valid I2C address */
876
                goto release;
877
 
878
        /* The busy flag should be clear again */
879
        if (inb_p(address + LM78_ADDR_REG_OFFSET) & 0x80)
880
                goto release;
881
 
882
        /* Explicitly prevent the misdetection of Winbond chips */
883
        outb_p(0x4f, address + LM78_ADDR_REG_OFFSET);
884
        val = inb_p(address + LM78_DATA_REG_OFFSET);
885
        if (val == 0xa3 || val == 0x5c)
886
                goto release;
887
 
888
        /* Explicitly prevent the misdetection of ITE chips */
889
        outb_p(0x58, address + LM78_ADDR_REG_OFFSET);
890
        val = inb_p(address + LM78_DATA_REG_OFFSET);
891
        if (val == 0x90)
892
                goto release;
893
 
894
        /* Determine the chip type */
895
        outb_p(LM78_REG_CHIPID, address + LM78_ADDR_REG_OFFSET);
896
        val = inb_p(address + LM78_DATA_REG_OFFSET);
897
        if (val == 0x00 || val == 0x20  /* LM78 */
898
         || val == 0x40                 /* LM78-J */
899
         || (val & 0xfe) == 0xc0)       /* LM79 */
900
                found = 1;
901
 
902
        if (found)
903
                pr_info("lm78: Found an %s chip at %#x\n",
904
                        val & 0x80 ? "LM79" : "LM78", (int)address);
905
 
906
 release:
907
        release_region(address, LM78_EXTENT);
908
        return found;
909
}
910
 
911
static int __init lm78_isa_device_add(unsigned short address)
912
{
913
        struct resource res = {
914
                .start  = address,
915
                .end    = address + LM78_EXTENT - 1,
916
                .name   = "lm78",
917
                .flags  = IORESOURCE_IO,
918
        };
919
        int err;
920
 
921
        pdev = platform_device_alloc("lm78", address);
922
        if (!pdev) {
923
                err = -ENOMEM;
924
                printk(KERN_ERR "lm78: Device allocation failed\n");
925
                goto exit;
926
        }
927
 
928
        err = platform_device_add_resources(pdev, &res, 1);
929
        if (err) {
930
                printk(KERN_ERR "lm78: Device resource addition failed "
931
                       "(%d)\n", err);
932
                goto exit_device_put;
933
        }
934
 
935
        err = platform_device_add(pdev);
936
        if (err) {
937
                printk(KERN_ERR "lm78: Device addition failed (%d)\n",
938
                       err);
939
                goto exit_device_put;
940
        }
941
 
942
        return 0;
943
 
944
 exit_device_put:
945
        platform_device_put(pdev);
946
 exit:
947
        pdev = NULL;
948
        return err;
949
}
950
 
951
static int __init sm_lm78_init(void)
952
{
953
        int res;
954
 
955
        res = i2c_add_driver(&lm78_driver);
956
        if (res)
957
                goto exit;
958
 
959
        if (lm78_isa_found(isa_address)) {
960
                res = platform_driver_register(&lm78_isa_driver);
961
                if (res)
962
                        goto exit_unreg_i2c_driver;
963
 
964
                /* Sets global pdev as a side effect */
965
                res = lm78_isa_device_add(isa_address);
966
                if (res)
967
                        goto exit_unreg_isa_driver;
968
        }
969
 
970
        return 0;
971
 
972
 exit_unreg_isa_driver:
973
        platform_driver_unregister(&lm78_isa_driver);
974
 exit_unreg_i2c_driver:
975
        i2c_del_driver(&lm78_driver);
976
 exit:
977
        return res;
978
}
979
 
980
static void __exit sm_lm78_exit(void)
981
{
982
        if (pdev) {
983
                platform_device_unregister(pdev);
984
                platform_driver_unregister(&lm78_isa_driver);
985
        }
986
        i2c_del_driver(&lm78_driver);
987
}
988
 
989
 
990
 
991
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
992
MODULE_DESCRIPTION("LM78/LM79 driver");
993
MODULE_LICENSE("GPL");
994
 
995
module_init(sm_lm78_init);
996
module_exit(sm_lm78_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.