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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [hwmon/] [adm9240.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
 * adm9240.c    Part of lm_sensors, Linux kernel modules for hardware
3
 *              monitoring
4
 *
5
 * Copyright (C) 1999   Frodo Looijaard <frodol@dds.nl>
6
 *                      Philip Edelbrock <phil@netroedge.com>
7
 * Copyright (C) 2003   Michiel Rook <michiel@grendelproject.nl>
8
 * Copyright (C) 2005   Grant Coady <gcoady.lk@gmail.com> with valuable
9
 *                              guidance from Jean Delvare
10
 *
11
 * Driver supports      Analog Devices          ADM9240
12
 *                      Dallas Semiconductor    DS1780
13
 *                      National Semiconductor  LM81
14
 *
15
 * ADM9240 is the reference, DS1780 and LM81 are register compatibles
16
 *
17
 * Voltage      Six inputs are scaled by chip, VID also reported
18
 * Temperature  Chip temperature to 0.5'C, maximum and max_hysteris
19
 * Fans         2 fans, low speed alarm, automatic fan clock divider
20
 * Alarms       16-bit map of active alarms
21
 * Analog Out   0..1250 mV output
22
 *
23
 * Chassis Intrusion: clear CI latch with 'echo 1 > chassis_clear'
24
 *
25
 * Test hardware: Intel SE440BX-2 desktop motherboard --Grant
26
 *
27
 * LM81 extended temp reading not implemented
28
 *
29
 * This program is free software; you can redistribute it and/or modify
30
 * it under the terms of the GNU General Public License as published by
31
 * the Free Software Foundation; either version 2 of the License, or
32
 * (at your option) any later version.
33
 *
34
 * This program is distributed in the hope that it will be useful,
35
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
37
 * GNU General Public License for more details.
38
 *
39
 * You should have received a copy of the GNU General Public License
40
 * along with this program; if not, write to the Free Software
41
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
42
 */
43
 
44
#include <linux/init.h>
45
#include <linux/module.h>
46
#include <linux/slab.h>
47
#include <linux/i2c.h>
48
#include <linux/hwmon-sysfs.h>
49
#include <linux/hwmon.h>
50
#include <linux/hwmon-vid.h>
51
#include <linux/err.h>
52
#include <linux/mutex.h>
53
 
54
/* Addresses to scan */
55
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
56
                                        I2C_CLIENT_END };
57
 
58
/* Insmod parameters */
59
I2C_CLIENT_INSMOD_3(adm9240, ds1780, lm81);
60
 
61
/* ADM9240 registers */
62
#define ADM9240_REG_MAN_ID              0x3e
63
#define ADM9240_REG_DIE_REV             0x3f
64
#define ADM9240_REG_CONFIG              0x40
65
 
66
#define ADM9240_REG_IN(nr)              (0x20 + (nr))   /* 0..5 */
67
#define ADM9240_REG_IN_MAX(nr)          (0x2b + (nr) * 2)
68
#define ADM9240_REG_IN_MIN(nr)          (0x2c + (nr) * 2)
69
#define ADM9240_REG_FAN(nr)             (0x28 + (nr))   /* 0..1 */
70
#define ADM9240_REG_FAN_MIN(nr)         (0x3b + (nr))
71
#define ADM9240_REG_INT(nr)             (0x41 + (nr))
72
#define ADM9240_REG_INT_MASK(nr)        (0x43 + (nr))
73
#define ADM9240_REG_TEMP                0x27
74
#define ADM9240_REG_TEMP_MAX(nr)        (0x39 + (nr)) /* 0, 1 = high, hyst */
75
#define ADM9240_REG_ANALOG_OUT          0x19
76
#define ADM9240_REG_CHASSIS_CLEAR       0x46
77
#define ADM9240_REG_VID_FAN_DIV         0x47
78
#define ADM9240_REG_I2C_ADDR            0x48
79
#define ADM9240_REG_VID4                0x49
80
#define ADM9240_REG_TEMP_CONF           0x4b
81
 
82
/* generalised scaling with integer rounding */
83
static inline int SCALE(long val, int mul, int div)
84
{
85
        if (val < 0)
86
                return (val * mul - div / 2) / div;
87
        else
88
                return (val * mul + div / 2) / div;
89
}
90
 
91
/* adm9240 internally scales voltage measurements */
92
static const u16 nom_mv[] = { 2500, 2700, 3300, 5000, 12000, 2700 };
93
 
94
static inline unsigned int IN_FROM_REG(u8 reg, int n)
95
{
96
        return SCALE(reg, nom_mv[n], 192);
97
}
98
 
99
static inline u8 IN_TO_REG(unsigned long val, int n)
100
{
101
        return SENSORS_LIMIT(SCALE(val, 192, nom_mv[n]), 0, 255);
102
}
103
 
104
/* temperature range: -40..125, 127 disables temperature alarm */
105
static inline s8 TEMP_TO_REG(long val)
106
{
107
        return SENSORS_LIMIT(SCALE(val, 1, 1000), -40, 127);
108
}
109
 
110
/* two fans, each with low fan speed limit */
111
static inline unsigned int FAN_FROM_REG(u8 reg, u8 div)
112
{
113
        if (!reg) /* error */
114
                return -1;
115
 
116
        if (reg == 255)
117
                return 0;
118
 
119
        return SCALE(1350000, 1, reg * div);
120
}
121
 
122
/* analog out 0..1250mV */
123
static inline u8 AOUT_TO_REG(unsigned long val)
124
{
125
        return SENSORS_LIMIT(SCALE(val, 255, 1250), 0, 255);
126
}
127
 
128
static inline unsigned int AOUT_FROM_REG(u8 reg)
129
{
130
        return SCALE(reg, 1250, 255);
131
}
132
 
133
static int adm9240_attach_adapter(struct i2c_adapter *adapter);
134
static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind);
135
static void adm9240_init_client(struct i2c_client *client);
136
static int adm9240_detach_client(struct i2c_client *client);
137
static struct adm9240_data *adm9240_update_device(struct device *dev);
138
 
139
/* driver data */
140
static struct i2c_driver adm9240_driver = {
141
        .driver = {
142
                .name   = "adm9240",
143
        },
144
        .id             = I2C_DRIVERID_ADM9240,
145
        .attach_adapter = adm9240_attach_adapter,
146
        .detach_client  = adm9240_detach_client,
147
};
148
 
149
/* per client data */
150
struct adm9240_data {
151
        enum chips type;
152
        struct i2c_client client;
153
        struct device *hwmon_dev;
154
        struct mutex update_lock;
155
        char valid;
156
        unsigned long last_updated_measure;
157
        unsigned long last_updated_config;
158
 
159
        u8 in[6];               /* ro   in0_input */
160
        u8 in_max[6];           /* rw   in0_max */
161
        u8 in_min[6];           /* rw   in0_min */
162
        u8 fan[2];              /* ro   fan1_input */
163
        u8 fan_min[2];          /* rw   fan1_min */
164
        u8 fan_div[2];          /* rw   fan1_div, read-only accessor */
165
        s16 temp;               /* ro   temp1_input, 9-bit sign-extended */
166
        s8 temp_max[2];         /* rw   0 -> temp_max, 1 -> temp_max_hyst */
167
        u16 alarms;             /* ro   alarms */
168
        u8 aout;                /* rw   aout_output */
169
        u8 vid;                 /* ro   vid */
170
        u8 vrm;                 /* --   vrm set on startup, no accessor */
171
};
172
 
173
/*** sysfs accessors ***/
174
 
175
/* temperature */
176
static ssize_t show_temp(struct device *dev, struct device_attribute *dummy,
177
                char *buf)
178
{
179
        struct adm9240_data *data = adm9240_update_device(dev);
180
        return sprintf(buf, "%d\n", data->temp * 500); /* 9-bit value */
181
}
182
 
183
static ssize_t show_max(struct device *dev, struct device_attribute *devattr,
184
                char *buf)
185
{
186
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
187
        struct adm9240_data *data = adm9240_update_device(dev);
188
        return sprintf(buf, "%d\n", data->temp_max[attr->index] * 1000);
189
}
190
 
191
static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
192
                const char *buf, size_t count)
193
{
194
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
195
        struct i2c_client *client = to_i2c_client(dev);
196
        struct adm9240_data *data = i2c_get_clientdata(client);
197
        long val = simple_strtol(buf, NULL, 10);
198
 
199
        mutex_lock(&data->update_lock);
200
        data->temp_max[attr->index] = TEMP_TO_REG(val);
201
        i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index),
202
                        data->temp_max[attr->index]);
203
        mutex_unlock(&data->update_lock);
204
        return count;
205
}
206
 
207
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL);
208
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
209
                show_max, set_max, 0);
210
static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
211
                show_max, set_max, 1);
212
 
213
/* voltage */
214
static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
215
                char *buf)
216
{
217
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
218
        struct adm9240_data *data = adm9240_update_device(dev);
219
        return sprintf(buf, "%d\n", IN_FROM_REG(data->in[attr->index],
220
                                attr->index));
221
}
222
 
223
static ssize_t show_in_min(struct device *dev,
224
                struct device_attribute *devattr, char *buf)
225
{
226
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
227
        struct adm9240_data *data = adm9240_update_device(dev);
228
        return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[attr->index],
229
                                attr->index));
230
}
231
 
232
static ssize_t show_in_max(struct device *dev,
233
                struct device_attribute *devattr, char *buf)
234
{
235
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
236
        struct adm9240_data *data = adm9240_update_device(dev);
237
        return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[attr->index],
238
                                attr->index));
239
}
240
 
241
static ssize_t set_in_min(struct device *dev,
242
                struct device_attribute *devattr,
243
                const char *buf, size_t count)
244
{
245
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
246
        struct i2c_client *client = to_i2c_client(dev);
247
        struct adm9240_data *data = i2c_get_clientdata(client);
248
        unsigned long val = simple_strtoul(buf, NULL, 10);
249
 
250
        mutex_lock(&data->update_lock);
251
        data->in_min[attr->index] = IN_TO_REG(val, attr->index);
252
        i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index),
253
                        data->in_min[attr->index]);
254
        mutex_unlock(&data->update_lock);
255
        return count;
256
}
257
 
258
static ssize_t set_in_max(struct device *dev,
259
                struct device_attribute *devattr,
260
                const char *buf, size_t count)
261
{
262
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
263
        struct i2c_client *client = to_i2c_client(dev);
264
        struct adm9240_data *data = i2c_get_clientdata(client);
265
        unsigned long val = simple_strtoul(buf, NULL, 10);
266
 
267
        mutex_lock(&data->update_lock);
268
        data->in_max[attr->index] = IN_TO_REG(val, attr->index);
269
        i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index),
270
                        data->in_max[attr->index]);
271
        mutex_unlock(&data->update_lock);
272
        return count;
273
}
274
 
275
#define vin(nr)                                                 \
276
static SENSOR_DEVICE_ATTR(in##nr##_input, S_IRUGO,              \
277
                show_in, NULL, nr);                             \
278
static SENSOR_DEVICE_ATTR(in##nr##_min, S_IRUGO | S_IWUSR,      \
279
                show_in_min, set_in_min, nr);                   \
280
static SENSOR_DEVICE_ATTR(in##nr##_max, S_IRUGO | S_IWUSR,      \
281
                show_in_max, set_in_max, nr);
282
 
283
vin(0);
284
vin(1);
285
vin(2);
286
vin(3);
287
vin(4);
288
vin(5);
289
 
290
/* fans */
291
static ssize_t show_fan(struct device *dev,
292
                struct device_attribute *devattr, char *buf)
293
{
294
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
295
        struct adm9240_data *data = adm9240_update_device(dev);
296
        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[attr->index],
297
                                1 << data->fan_div[attr->index]));
298
}
299
 
300
static ssize_t show_fan_min(struct device *dev,
301
                struct device_attribute *devattr, char *buf)
302
{
303
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
304
        struct adm9240_data *data = adm9240_update_device(dev);
305
        return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan_min[attr->index],
306
                                1 << data->fan_div[attr->index]));
307
}
308
 
309
static ssize_t show_fan_div(struct device *dev,
310
                struct device_attribute *devattr, char *buf)
311
{
312
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
313
        struct adm9240_data *data = adm9240_update_device(dev);
314
        return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
315
}
316
 
317
/* write new fan div, callers must hold data->update_lock */
318
static void adm9240_write_fan_div(struct i2c_client *client, int nr,
319
                u8 fan_div)
320
{
321
        u8 reg, old, shift = (nr + 2) * 2;
322
 
323
        reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
324
        old = (reg >> shift) & 3;
325
        reg &= ~(3 << shift);
326
        reg |= (fan_div << shift);
327
        i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
328
        dev_dbg(&client->dev, "fan%d clock divider changed from %u "
329
                        "to %u\n", nr + 1, 1 << old, 1 << fan_div);
330
}
331
 
332
/*
333
 * set fan speed low limit:
334
 *
335
 * - value is zero: disable fan speed low limit alarm
336
 *
337
 * - value is below fan speed measurement range: enable fan speed low
338
 *   limit alarm to be asserted while fan speed too slow to measure
339
 *
340
 * - otherwise: select fan clock divider to suit fan speed low limit,
341
 *   measurement code may adjust registers to ensure fan speed reading
342
 */
343
static ssize_t set_fan_min(struct device *dev,
344
                struct device_attribute *devattr,
345
                const char *buf, size_t count)
346
{
347
        struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
348
        struct i2c_client *client = to_i2c_client(dev);
349
        struct adm9240_data *data = i2c_get_clientdata(client);
350
        unsigned long val = simple_strtoul(buf, NULL, 10);
351
        int nr = attr->index;
352
        u8 new_div;
353
 
354
        mutex_lock(&data->update_lock);
355
 
356
        if (!val) {
357
                data->fan_min[nr] = 255;
358
                new_div = data->fan_div[nr];
359
 
360
                dev_dbg(&client->dev, "fan%u low limit set disabled\n",
361
                                nr + 1);
362
 
363
        } else if (val < 1350000 / (8 * 254)) {
364
                new_div = 3;
365
                data->fan_min[nr] = 254;
366
 
367
                dev_dbg(&client->dev, "fan%u low limit set minimum %u\n",
368
                                nr + 1, FAN_FROM_REG(254, 1 << new_div));
369
 
370
        } else {
371
                unsigned int new_min = 1350000 / val;
372
 
373
                new_div = 0;
374
                while (new_min > 192 && new_div < 3) {
375
                        new_div++;
376
                        new_min /= 2;
377
                }
378
                if (!new_min) /* keep > 0 */
379
                        new_min++;
380
 
381
                data->fan_min[nr] = new_min;
382
 
383
                dev_dbg(&client->dev, "fan%u low limit set fan speed %u\n",
384
                                nr + 1, FAN_FROM_REG(new_min, 1 << new_div));
385
        }
386
 
387
        if (new_div != data->fan_div[nr]) {
388
                data->fan_div[nr] = new_div;
389
                adm9240_write_fan_div(client, nr, new_div);
390
        }
391
        i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(nr),
392
                        data->fan_min[nr]);
393
 
394
        mutex_unlock(&data->update_lock);
395
        return count;
396
}
397
 
398
#define fan(nr)                                                 \
399
static SENSOR_DEVICE_ATTR(fan##nr##_input, S_IRUGO,             \
400
                show_fan, NULL, nr - 1);                        \
401
static SENSOR_DEVICE_ATTR(fan##nr##_div, S_IRUGO,               \
402
                show_fan_div, NULL, nr - 1);                    \
403
static SENSOR_DEVICE_ATTR(fan##nr##_min, S_IRUGO | S_IWUSR,     \
404
                show_fan_min, set_fan_min, nr - 1);
405
 
406
fan(1);
407
fan(2);
408
 
409
/* alarms */
410
static ssize_t show_alarms(struct device *dev,
411
                struct device_attribute *attr, char *buf)
412
{
413
        struct adm9240_data *data = adm9240_update_device(dev);
414
        return sprintf(buf, "%u\n", data->alarms);
415
}
416
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
417
 
418
/* vid */
419
static ssize_t show_vid(struct device *dev,
420
                struct device_attribute *attr, char *buf)
421
{
422
        struct adm9240_data *data = adm9240_update_device(dev);
423
        return sprintf(buf, "%d\n", vid_from_reg(data->vid, data->vrm));
424
}
425
static DEVICE_ATTR(cpu0_vid, S_IRUGO, show_vid, NULL);
426
 
427
/* analog output */
428
static ssize_t show_aout(struct device *dev,
429
                struct device_attribute *attr, char *buf)
430
{
431
        struct adm9240_data *data = adm9240_update_device(dev);
432
        return sprintf(buf, "%d\n", AOUT_FROM_REG(data->aout));
433
}
434
 
435
static ssize_t set_aout(struct device *dev,
436
                struct device_attribute *attr,
437
                const char *buf, size_t count)
438
{
439
        struct i2c_client *client = to_i2c_client(dev);
440
        struct adm9240_data *data = i2c_get_clientdata(client);
441
        unsigned long val = simple_strtol(buf, NULL, 10);
442
 
443
        mutex_lock(&data->update_lock);
444
        data->aout = AOUT_TO_REG(val);
445
        i2c_smbus_write_byte_data(client, ADM9240_REG_ANALOG_OUT, data->aout);
446
        mutex_unlock(&data->update_lock);
447
        return count;
448
}
449
static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
450
 
451
/* chassis_clear */
452
static ssize_t chassis_clear(struct device *dev,
453
                struct device_attribute *attr,
454
                const char *buf, size_t count)
455
{
456
        struct i2c_client *client = to_i2c_client(dev);
457
        unsigned long val = simple_strtol(buf, NULL, 10);
458
 
459
        if (val == 1) {
460
                i2c_smbus_write_byte_data(client,
461
                                ADM9240_REG_CHASSIS_CLEAR, 0x80);
462
                dev_dbg(&client->dev, "chassis intrusion latch cleared\n");
463
        }
464
        return count;
465
}
466
static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear);
467
 
468
static struct attribute *adm9240_attributes[] = {
469
        &sensor_dev_attr_in0_input.dev_attr.attr,
470
        &sensor_dev_attr_in0_min.dev_attr.attr,
471
        &sensor_dev_attr_in0_max.dev_attr.attr,
472
        &sensor_dev_attr_in1_input.dev_attr.attr,
473
        &sensor_dev_attr_in1_min.dev_attr.attr,
474
        &sensor_dev_attr_in1_max.dev_attr.attr,
475
        &sensor_dev_attr_in2_input.dev_attr.attr,
476
        &sensor_dev_attr_in2_min.dev_attr.attr,
477
        &sensor_dev_attr_in2_max.dev_attr.attr,
478
        &sensor_dev_attr_in3_input.dev_attr.attr,
479
        &sensor_dev_attr_in3_min.dev_attr.attr,
480
        &sensor_dev_attr_in3_max.dev_attr.attr,
481
        &sensor_dev_attr_in4_input.dev_attr.attr,
482
        &sensor_dev_attr_in4_min.dev_attr.attr,
483
        &sensor_dev_attr_in4_max.dev_attr.attr,
484
        &sensor_dev_attr_in5_input.dev_attr.attr,
485
        &sensor_dev_attr_in5_min.dev_attr.attr,
486
        &sensor_dev_attr_in5_max.dev_attr.attr,
487
        &dev_attr_temp1_input.attr,
488
        &sensor_dev_attr_temp1_max.dev_attr.attr,
489
        &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
490
        &sensor_dev_attr_fan1_input.dev_attr.attr,
491
        &sensor_dev_attr_fan1_div.dev_attr.attr,
492
        &sensor_dev_attr_fan1_min.dev_attr.attr,
493
        &sensor_dev_attr_fan2_input.dev_attr.attr,
494
        &sensor_dev_attr_fan2_div.dev_attr.attr,
495
        &sensor_dev_attr_fan2_min.dev_attr.attr,
496
        &dev_attr_alarms.attr,
497
        &dev_attr_aout_output.attr,
498
        &dev_attr_chassis_clear.attr,
499
        &dev_attr_cpu0_vid.attr,
500
        NULL
501
};
502
 
503
static const struct attribute_group adm9240_group = {
504
        .attrs = adm9240_attributes,
505
};
506
 
507
 
508
/*** sensor chip detect and driver install ***/
509
 
510
static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
511
{
512
        struct i2c_client *new_client;
513
        struct adm9240_data *data;
514
        int err = 0;
515
        const char *name = "";
516
        u8 man_id, die_rev;
517
 
518
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
519
                goto exit;
520
 
521
        if (!(data = kzalloc(sizeof(*data), GFP_KERNEL))) {
522
                err = -ENOMEM;
523
                goto exit;
524
        }
525
 
526
        new_client = &data->client;
527
        i2c_set_clientdata(new_client, data);
528
        new_client->addr = address;
529
        new_client->adapter = adapter;
530
        new_client->driver = &adm9240_driver;
531
        new_client->flags = 0;
532
 
533
        if (kind == 0) {
534
                kind = adm9240;
535
        }
536
 
537
        if (kind < 0) {
538
 
539
                /* verify chip: reg address should match i2c address */
540
                if (i2c_smbus_read_byte_data(new_client, ADM9240_REG_I2C_ADDR)
541
                                != address) {
542
                        dev_err(&adapter->dev, "detect fail: address match, "
543
                                        "0x%02x\n", address);
544
                        goto exit_free;
545
                }
546
 
547
                /* check known chip manufacturer */
548
                man_id = i2c_smbus_read_byte_data(new_client,
549
                                ADM9240_REG_MAN_ID);
550
                if (man_id == 0x23) {
551
                        kind = adm9240;
552
                } else if (man_id == 0xda) {
553
                        kind = ds1780;
554
                } else if (man_id == 0x01) {
555
                        kind = lm81;
556
                } else {
557
                        dev_err(&adapter->dev, "detect fail: unknown manuf, "
558
                                        "0x%02x\n", man_id);
559
                        goto exit_free;
560
                }
561
 
562
                /* successful detect, print chip info */
563
                die_rev = i2c_smbus_read_byte_data(new_client,
564
                                ADM9240_REG_DIE_REV);
565
                dev_info(&adapter->dev, "found %s revision %u\n",
566
                                man_id == 0x23 ? "ADM9240" :
567
                                man_id == 0xda ? "DS1780" : "LM81", die_rev);
568
        }
569
 
570
        /* either forced or detected chip kind */
571
        if (kind == adm9240) {
572
                name = "adm9240";
573
        } else if (kind == ds1780) {
574
                name = "ds1780";
575
        } else if (kind == lm81) {
576
                name = "lm81";
577
        }
578
 
579
        /* fill in the remaining client fields and attach */
580
        strlcpy(new_client->name, name, I2C_NAME_SIZE);
581
        data->type = kind;
582
        mutex_init(&data->update_lock);
583
 
584
        if ((err = i2c_attach_client(new_client)))
585
                goto exit_free;
586
 
587
        adm9240_init_client(new_client);
588
 
589
        /* populate sysfs filesystem */
590
        if ((err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group)))
591
                goto exit_detach;
592
 
593
        data->hwmon_dev = hwmon_device_register(&new_client->dev);
594
        if (IS_ERR(data->hwmon_dev)) {
595
                err = PTR_ERR(data->hwmon_dev);
596
                goto exit_remove;
597
        }
598
 
599
        return 0;
600
 
601
exit_remove:
602
        sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
603
exit_detach:
604
        i2c_detach_client(new_client);
605
exit_free:
606
        kfree(data);
607
exit:
608
        return err;
609
}
610
 
611
static int adm9240_attach_adapter(struct i2c_adapter *adapter)
612
{
613
        if (!(adapter->class & I2C_CLASS_HWMON))
614
                return 0;
615
        return i2c_probe(adapter, &addr_data, adm9240_detect);
616
}
617
 
618
static int adm9240_detach_client(struct i2c_client *client)
619
{
620
        struct adm9240_data *data = i2c_get_clientdata(client);
621
        int err;
622
 
623
        hwmon_device_unregister(data->hwmon_dev);
624
        sysfs_remove_group(&client->dev.kobj, &adm9240_group);
625
 
626
        if ((err = i2c_detach_client(client)))
627
                return err;
628
 
629
        kfree(data);
630
        return 0;
631
}
632
 
633
static void adm9240_init_client(struct i2c_client *client)
634
{
635
        struct adm9240_data *data = i2c_get_clientdata(client);
636
        u8 conf = i2c_smbus_read_byte_data(client, ADM9240_REG_CONFIG);
637
        u8 mode = i2c_smbus_read_byte_data(client, ADM9240_REG_TEMP_CONF) & 3;
638
 
639
        data->vrm = vid_which_vrm(); /* need this to report vid as mV */
640
 
641
        dev_info(&client->dev, "Using VRM: %d.%d\n", data->vrm / 10,
642
                        data->vrm % 10);
643
 
644
        if (conf & 1) { /* measurement cycle running: report state */
645
 
646
                dev_info(&client->dev, "status: config 0x%02x mode %u\n",
647
                                conf, mode);
648
 
649
        } else { /* cold start: open limits before starting chip */
650
                int i;
651
 
652
                for (i = 0; i < 6; i++)
653
                {
654
                        i2c_smbus_write_byte_data(client,
655
                                        ADM9240_REG_IN_MIN(i), 0);
656
                        i2c_smbus_write_byte_data(client,
657
                                        ADM9240_REG_IN_MAX(i), 255);
658
                }
659
                i2c_smbus_write_byte_data(client,
660
                                ADM9240_REG_FAN_MIN(0), 255);
661
                i2c_smbus_write_byte_data(client,
662
                                ADM9240_REG_FAN_MIN(1), 255);
663
                i2c_smbus_write_byte_data(client,
664
                                ADM9240_REG_TEMP_MAX(0), 127);
665
                i2c_smbus_write_byte_data(client,
666
                                ADM9240_REG_TEMP_MAX(1), 127);
667
 
668
                /* start measurement cycle */
669
                i2c_smbus_write_byte_data(client, ADM9240_REG_CONFIG, 1);
670
 
671
                dev_info(&client->dev, "cold start: config was 0x%02x "
672
                                "mode %u\n", conf, mode);
673
        }
674
}
675
 
676
static struct adm9240_data *adm9240_update_device(struct device *dev)
677
{
678
        struct i2c_client *client = to_i2c_client(dev);
679
        struct adm9240_data *data = i2c_get_clientdata(client);
680
        int i;
681
 
682
        mutex_lock(&data->update_lock);
683
 
684
        /* minimum measurement cycle: 1.75 seconds */
685
        if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
686
                        || !data->valid) {
687
 
688
                for (i = 0; i < 6; i++) /* read voltages */
689
                {
690
                        data->in[i] = i2c_smbus_read_byte_data(client,
691
                                        ADM9240_REG_IN(i));
692
                }
693
                data->alarms = i2c_smbus_read_byte_data(client,
694
                                        ADM9240_REG_INT(0)) |
695
                                        i2c_smbus_read_byte_data(client,
696
                                        ADM9240_REG_INT(1)) << 8;
697
 
698
                /* read temperature: assume temperature changes less than
699
                 * 0.5'C per two measurement cycles thus ignore possible
700
                 * but unlikely aliasing error on lsb reading. --Grant */
701
                data->temp = ((i2c_smbus_read_byte_data(client,
702
                                        ADM9240_REG_TEMP) << 8) |
703
                                        i2c_smbus_read_byte_data(client,
704
                                        ADM9240_REG_TEMP_CONF)) / 128;
705
 
706
                for (i = 0; i < 2; i++) /* read fans */
707
                {
708
                        data->fan[i] = i2c_smbus_read_byte_data(client,
709
                                        ADM9240_REG_FAN(i));
710
 
711
                        /* adjust fan clock divider on overflow */
712
                        if (data->valid && data->fan[i] == 255 &&
713
                                        data->fan_div[i] < 3) {
714
 
715
                                adm9240_write_fan_div(client, i,
716
                                                ++data->fan_div[i]);
717
 
718
                                /* adjust fan_min if active, but not to 0 */
719
                                if (data->fan_min[i] < 255 &&
720
                                                data->fan_min[i] >= 2)
721
                                        data->fan_min[i] /= 2;
722
                        }
723
                }
724
                data->last_updated_measure = jiffies;
725
        }
726
 
727
        /* minimum config reading cycle: 300 seconds */
728
        if (time_after(jiffies, data->last_updated_config + (HZ * 300))
729
                        || !data->valid) {
730
 
731
                for (i = 0; i < 6; i++)
732
                {
733
                        data->in_min[i] = i2c_smbus_read_byte_data(client,
734
                                        ADM9240_REG_IN_MIN(i));
735
                        data->in_max[i] = i2c_smbus_read_byte_data(client,
736
                                        ADM9240_REG_IN_MAX(i));
737
                }
738
                for (i = 0; i < 2; i++)
739
                {
740
                        data->fan_min[i] = i2c_smbus_read_byte_data(client,
741
                                        ADM9240_REG_FAN_MIN(i));
742
                }
743
                data->temp_max[0] = i2c_smbus_read_byte_data(client,
744
                                ADM9240_REG_TEMP_MAX(0));
745
                data->temp_max[1] = i2c_smbus_read_byte_data(client,
746
                                ADM9240_REG_TEMP_MAX(1));
747
 
748
                /* read fan divs and 5-bit VID */
749
                i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
750
                data->fan_div[0] = (i >> 4) & 3;
751
                data->fan_div[1] = (i >> 6) & 3;
752
                data->vid = i & 0x0f;
753
                data->vid |= (i2c_smbus_read_byte_data(client,
754
                                        ADM9240_REG_VID4) & 1) << 4;
755
                /* read analog out */
756
                data->aout = i2c_smbus_read_byte_data(client,
757
                                ADM9240_REG_ANALOG_OUT);
758
 
759
                data->last_updated_config = jiffies;
760
                data->valid = 1;
761
        }
762
        mutex_unlock(&data->update_lock);
763
        return data;
764
}
765
 
766
static int __init sensors_adm9240_init(void)
767
{
768
        return i2c_add_driver(&adm9240_driver);
769
}
770
 
771
static void __exit sensors_adm9240_exit(void)
772
{
773
        i2c_del_driver(&adm9240_driver);
774
}
775
 
776
MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, "
777
                "Grant Coady <gcoady.lk@gmail.com> and others");
778
MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver");
779
MODULE_LICENSE("GPL");
780
 
781
module_init(sensors_adm9240_init);
782
module_exit(sensors_adm9240_exit);
783
 

powered by: WebSVN 2.1.0

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