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

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [hwmon/] [adm1021.c] - Blame information for rev 62

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
    adm1021.c - Part of lm_sensors, Linux kernel modules for hardware
3
                monitoring
4
    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> and
5
    Philip Edelbrock <phil@netroedge.com>
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/hwmon.h>
28
#include <linux/hwmon-sysfs.h>
29
#include <linux/err.h>
30
#include <linux/mutex.h>
31
 
32
 
33
/* Addresses to scan */
34
static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
35
                                        0x29, 0x2a, 0x2b,
36
                                        0x4c, 0x4d, 0x4e,
37
                                        I2C_CLIENT_END };
38
 
39
/* Insmod parameters */
40
I2C_CLIENT_INSMOD_8(adm1021, adm1023, max1617, max1617a, thmc10, lm84, gl523sm,
41
                        mc1066);
42
 
43
/* adm1021 constants specified below */
44
 
45
/* The adm1021 registers */
46
/* Read-only */
47
/* For nr in 0-1 */
48
#define ADM1021_REG_TEMP(nr)            (nr)
49
#define ADM1021_REG_STATUS              0x02
50
/* 0x41 = AD, 0x49 = TI, 0x4D = Maxim, 0x23 = Genesys , 0x54 = Onsemi */
51
#define ADM1021_REG_MAN_ID              0xFE
52
/* ADM1021 = 0x0X, ADM1023 = 0x3X */
53
#define ADM1021_REG_DEV_ID              0xFF
54
/* These use different addresses for reading/writing */
55
#define ADM1021_REG_CONFIG_R            0x03
56
#define ADM1021_REG_CONFIG_W            0x09
57
#define ADM1021_REG_CONV_RATE_R         0x04
58
#define ADM1021_REG_CONV_RATE_W         0x0A
59
/* These are for the ADM1023's additional precision on the remote temp sensor */
60
#define ADM1023_REG_REM_TEMP_PREC       0x10
61
#define ADM1023_REG_REM_OFFSET          0x11
62
#define ADM1023_REG_REM_OFFSET_PREC     0x12
63
#define ADM1023_REG_REM_TOS_PREC        0x13
64
#define ADM1023_REG_REM_THYST_PREC      0x14
65
/* limits */
66
/* For nr in 0-1 */
67
#define ADM1021_REG_TOS_R(nr)           (0x05 + 2 * (nr))
68
#define ADM1021_REG_TOS_W(nr)           (0x0B + 2 * (nr))
69
#define ADM1021_REG_THYST_R(nr)         (0x06 + 2 * (nr))
70
#define ADM1021_REG_THYST_W(nr)         (0x0C + 2 * (nr))
71
/* write-only */
72
#define ADM1021_REG_ONESHOT             0x0F
73
 
74
/* Initial values */
75
 
76
/* Note: Even though I left the low and high limits named os and hyst,
77
they don't quite work like a thermostat the way the LM75 does.  I.e.,
78
a lower temp than THYST actually triggers an alarm instead of
79
clearing it.  Weird, ey?   --Phil  */
80
 
81
/* Each client has this additional data */
82
struct adm1021_data {
83
        struct i2c_client client;
84
        struct device *hwmon_dev;
85
        enum chips type;
86
 
87
        struct mutex update_lock;
88
        char valid;             /* !=0 if following fields are valid */
89
        unsigned long last_updated;     /* In jiffies */
90
 
91
        s8 temp_max[2];         /* Register values */
92
        s8 temp_min[2];
93
        s8 temp[2];
94
        u8 alarms;
95
        /* Special values for ADM1023 only */
96
        u8 remote_temp_prec;
97
        u8 remote_temp_os_prec;
98
        u8 remote_temp_hyst_prec;
99
        u8 remote_temp_offset;
100
        u8 remote_temp_offset_prec;
101
};
102
 
103
static int adm1021_attach_adapter(struct i2c_adapter *adapter);
104
static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind);
105
static void adm1021_init_client(struct i2c_client *client);
106
static int adm1021_detach_client(struct i2c_client *client);
107
static struct adm1021_data *adm1021_update_device(struct device *dev);
108
 
109
/* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
110
static int read_only;
111
 
112
 
113
/* This is the driver that will be inserted */
114
static struct i2c_driver adm1021_driver = {
115
        .driver = {
116
                .name   = "adm1021",
117
        },
118
        .id             = I2C_DRIVERID_ADM1021,
119
        .attach_adapter = adm1021_attach_adapter,
120
        .detach_client  = adm1021_detach_client,
121
};
122
 
123
static ssize_t show_temp(struct device *dev,
124
                         struct device_attribute *devattr, char *buf)
125
{
126
        int index = to_sensor_dev_attr(devattr)->index;
127
        struct adm1021_data *data = adm1021_update_device(dev);
128
 
129
        return sprintf(buf, "%d\n", 1000 * data->temp[index]);
130
}
131
 
132
static ssize_t show_temp_max(struct device *dev,
133
                             struct device_attribute *devattr, char *buf)
134
{
135
        int index = to_sensor_dev_attr(devattr)->index;
136
        struct adm1021_data *data = adm1021_update_device(dev);
137
 
138
        return sprintf(buf, "%d\n", 1000 * data->temp_max[index]);
139
}
140
 
141
static ssize_t show_temp_min(struct device *dev,
142
                             struct device_attribute *devattr, char *buf)
143
{
144
        int index = to_sensor_dev_attr(devattr)->index;
145
        struct adm1021_data *data = adm1021_update_device(dev);
146
 
147
        return sprintf(buf, "%d\n", 1000 * data->temp_min[index]);
148
}
149
 
150
static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
151
                          char *buf)
152
{
153
        int index = to_sensor_dev_attr(attr)->index;
154
        struct adm1021_data *data = adm1021_update_device(dev);
155
        return sprintf(buf, "%u\n", (data->alarms >> index) & 1);
156
}
157
 
158
static ssize_t show_alarms(struct device *dev,
159
                           struct device_attribute *attr,
160
                           char *buf)
161
{
162
        struct adm1021_data *data = adm1021_update_device(dev);
163
        return sprintf(buf, "%u\n", data->alarms);
164
}
165
 
166
static ssize_t set_temp_max(struct device *dev,
167
                            struct device_attribute *devattr,
168
                            const char *buf, size_t count)
169
{
170
        int index = to_sensor_dev_attr(devattr)->index;
171
        struct i2c_client *client = to_i2c_client(dev);
172
        struct adm1021_data *data = i2c_get_clientdata(client);
173
        long temp = simple_strtol(buf, NULL, 10) / 1000;
174
 
175
        mutex_lock(&data->update_lock);
176
        data->temp_max[index] = SENSORS_LIMIT(temp, -128, 127);
177
        if (!read_only)
178
                i2c_smbus_write_byte_data(client, ADM1021_REG_TOS_W(index),
179
                                          data->temp_max[index]);
180
        mutex_unlock(&data->update_lock);
181
 
182
        return count;
183
}
184
 
185
static ssize_t set_temp_min(struct device *dev,
186
                            struct device_attribute *devattr,
187
                            const char *buf, size_t count)
188
{
189
        int index = to_sensor_dev_attr(devattr)->index;
190
        struct i2c_client *client = to_i2c_client(dev);
191
        struct adm1021_data *data = i2c_get_clientdata(client);
192
        long temp = simple_strtol(buf, NULL, 10) / 1000;
193
 
194
        mutex_lock(&data->update_lock);
195
        data->temp_min[index] = SENSORS_LIMIT(temp, -128, 127);
196
        if (!read_only)
197
                i2c_smbus_write_byte_data(client, ADM1021_REG_THYST_W(index),
198
                                          data->temp_min[index]);
199
        mutex_unlock(&data->update_lock);
200
 
201
        return count;
202
}
203
 
204
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0);
205
static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
206
                          set_temp_max, 0);
207
static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, show_temp_min,
208
                          set_temp_min, 0);
209
static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1);
210
static SENSOR_DEVICE_ATTR(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
211
                          set_temp_max, 1);
212
static SENSOR_DEVICE_ATTR(temp2_min, S_IWUSR | S_IRUGO, show_temp_min,
213
                          set_temp_min, 1);
214
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
215
static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 5);
216
static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
217
static SENSOR_DEVICE_ATTR(temp2_min_alarm, S_IRUGO, show_alarm, NULL, 3);
218
static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
219
 
220
static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
221
 
222
static int adm1021_attach_adapter(struct i2c_adapter *adapter)
223
{
224
        if (!(adapter->class & I2C_CLASS_HWMON))
225
                return 0;
226
        return i2c_probe(adapter, &addr_data, adm1021_detect);
227
}
228
 
229
static struct attribute *adm1021_attributes[] = {
230
        &sensor_dev_attr_temp1_max.dev_attr.attr,
231
        &sensor_dev_attr_temp1_min.dev_attr.attr,
232
        &sensor_dev_attr_temp1_input.dev_attr.attr,
233
        &sensor_dev_attr_temp2_max.dev_attr.attr,
234
        &sensor_dev_attr_temp2_min.dev_attr.attr,
235
        &sensor_dev_attr_temp2_input.dev_attr.attr,
236
        &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
237
        &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
238
        &sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
239
        &sensor_dev_attr_temp2_min_alarm.dev_attr.attr,
240
        &sensor_dev_attr_temp2_fault.dev_attr.attr,
241
        &dev_attr_alarms.attr,
242
        NULL
243
};
244
 
245
static const struct attribute_group adm1021_group = {
246
        .attrs = adm1021_attributes,
247
};
248
 
249
static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
250
{
251
        int i;
252
        struct i2c_client *client;
253
        struct adm1021_data *data;
254
        int err = 0;
255
        const char *type_name = "";
256
        int conv_rate, status, config;
257
 
258
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
259
                pr_debug("adm1021: detect failed, "
260
                         "smbus byte data not supported!\n");
261
                goto error0;
262
        }
263
 
264
        /* OK. For now, we presume we have a valid client. We now create the
265
           client structure, even though we cannot fill it completely yet.
266
           But it allows us to access adm1021 register values. */
267
 
268
        if (!(data = kzalloc(sizeof(struct adm1021_data), GFP_KERNEL))) {
269
                pr_debug("adm1021: detect failed, kzalloc failed!\n");
270
                err = -ENOMEM;
271
                goto error0;
272
        }
273
 
274
        client = &data->client;
275
        i2c_set_clientdata(client, data);
276
        client->addr = address;
277
        client->adapter = adapter;
278
        client->driver = &adm1021_driver;
279
        status = i2c_smbus_read_byte_data(client, ADM1021_REG_STATUS);
280
        conv_rate = i2c_smbus_read_byte_data(client,
281
                                             ADM1021_REG_CONV_RATE_R);
282
        config = i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R);
283
 
284
        /* Now, we do the remaining detection. */
285
        if (kind < 0) {
286
                if ((status & 0x03) != 0x00 || (config & 0x3F) != 0x00
287
                    || (conv_rate & 0xF8) != 0x00) {
288
                        pr_debug("adm1021: detect failed, "
289
                                 "chip not detected!\n");
290
                        err = -ENODEV;
291
                        goto error1;
292
                }
293
        }
294
 
295
        /* Determine the chip type. */
296
        if (kind <= 0) {
297
                i = i2c_smbus_read_byte_data(client, ADM1021_REG_MAN_ID);
298
                if (i == 0x41)
299
                        if ((i2c_smbus_read_byte_data(client,
300
                                        ADM1021_REG_DEV_ID) & 0xF0) == 0x30)
301
                                kind = adm1023;
302
                        else
303
                                kind = adm1021;
304
                else if (i == 0x49)
305
                        kind = thmc10;
306
                else if (i == 0x23)
307
                        kind = gl523sm;
308
                else if ((i == 0x4d) &&
309
                         (i2c_smbus_read_byte_data(client,
310
                                                   ADM1021_REG_DEV_ID) == 0x01))
311
                        kind = max1617a;
312
                else if (i == 0x54)
313
                        kind = mc1066;
314
                /* LM84 Mfr ID in a different place, and it has more unused bits */
315
                else if (conv_rate == 0x00
316
                         && (kind == 0 /* skip extra detection */
317
                             || ((config & 0x7F) == 0x00
318
                                 && (status & 0xAB) == 0x00)))
319
                        kind = lm84;
320
                else
321
                        kind = max1617;
322
        }
323
 
324
        if (kind == max1617) {
325
                type_name = "max1617";
326
        } else if (kind == max1617a) {
327
                type_name = "max1617a";
328
        } else if (kind == adm1021) {
329
                type_name = "adm1021";
330
        } else if (kind == adm1023) {
331
                type_name = "adm1023";
332
        } else if (kind == thmc10) {
333
                type_name = "thmc10";
334
        } else if (kind == lm84) {
335
                type_name = "lm84";
336
        } else if (kind == gl523sm) {
337
                type_name = "gl523sm";
338
        } else if (kind == mc1066) {
339
                type_name = "mc1066";
340
        }
341
        pr_debug("adm1021: Detected chip %s at adapter %d, address 0x%02x.\n",
342
                 type_name, i2c_adapter_id(adapter), address);
343
 
344
        /* Fill in the remaining client fields */
345
        strlcpy(client->name, type_name, I2C_NAME_SIZE);
346
        data->type = kind;
347
        mutex_init(&data->update_lock);
348
 
349
        /* Tell the I2C layer a new client has arrived */
350
        if ((err = i2c_attach_client(client)))
351
                goto error1;
352
 
353
        /* Initialize the ADM1021 chip */
354
        if (kind != lm84 && !read_only)
355
                adm1021_init_client(client);
356
 
357
        /* Register sysfs hooks */
358
        if ((err = sysfs_create_group(&client->dev.kobj, &adm1021_group)))
359
                goto error2;
360
 
361
        data->hwmon_dev = hwmon_device_register(&client->dev);
362
        if (IS_ERR(data->hwmon_dev)) {
363
                err = PTR_ERR(data->hwmon_dev);
364
                goto error3;
365
        }
366
 
367
        return 0;
368
 
369
error3:
370
        sysfs_remove_group(&client->dev.kobj, &adm1021_group);
371
error2:
372
        i2c_detach_client(client);
373
error1:
374
        kfree(data);
375
error0:
376
        return err;
377
}
378
 
379
static void adm1021_init_client(struct i2c_client *client)
380
{
381
        /* Enable ADC and disable suspend mode */
382
        i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
383
                i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
384
        /* Set Conversion rate to 1/sec (this can be tinkered with) */
385
        i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
386
}
387
 
388
static int adm1021_detach_client(struct i2c_client *client)
389
{
390
        struct adm1021_data *data = i2c_get_clientdata(client);
391
        int err;
392
 
393
        hwmon_device_unregister(data->hwmon_dev);
394
        sysfs_remove_group(&client->dev.kobj, &adm1021_group);
395
 
396
        if ((err = i2c_detach_client(client)))
397
                return err;
398
 
399
        kfree(data);
400
        return 0;
401
}
402
 
403
static struct adm1021_data *adm1021_update_device(struct device *dev)
404
{
405
        struct i2c_client *client = to_i2c_client(dev);
406
        struct adm1021_data *data = i2c_get_clientdata(client);
407
 
408
        mutex_lock(&data->update_lock);
409
 
410
        if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
411
            || !data->valid) {
412
                int i;
413
 
414
                dev_dbg(&client->dev, "Starting adm1021 update\n");
415
 
416
                for (i = 0; i < 2; i++) {
417
                        data->temp[i] = i2c_smbus_read_byte_data(client,
418
                                                ADM1021_REG_TEMP(i));
419
                        data->temp_max[i] = i2c_smbus_read_byte_data(client,
420
                                                ADM1021_REG_TOS_R(i));
421
                        data->temp_min[i] = i2c_smbus_read_byte_data(client,
422
                                                ADM1021_REG_THYST_R(i));
423
                }
424
                data->alarms = i2c_smbus_read_byte_data(client,
425
                                                ADM1021_REG_STATUS) & 0x7c;
426
                if (data->type == adm1023) {
427
                        data->remote_temp_prec =
428
                                i2c_smbus_read_byte_data(client,
429
                                                ADM1023_REG_REM_TEMP_PREC);
430
                        data->remote_temp_os_prec =
431
                                i2c_smbus_read_byte_data(client,
432
                                                ADM1023_REG_REM_TOS_PREC);
433
                        data->remote_temp_hyst_prec =
434
                                i2c_smbus_read_byte_data(client,
435
                                                ADM1023_REG_REM_THYST_PREC);
436
                        data->remote_temp_offset =
437
                                i2c_smbus_read_byte_data(client,
438
                                                ADM1023_REG_REM_OFFSET);
439
                        data->remote_temp_offset_prec =
440
                                i2c_smbus_read_byte_data(client,
441
                                                ADM1023_REG_REM_OFFSET_PREC);
442
                }
443
                data->last_updated = jiffies;
444
                data->valid = 1;
445
        }
446
 
447
        mutex_unlock(&data->update_lock);
448
 
449
        return data;
450
}
451
 
452
static int __init sensors_adm1021_init(void)
453
{
454
        return i2c_add_driver(&adm1021_driver);
455
}
456
 
457
static void __exit sensors_adm1021_exit(void)
458
{
459
        i2c_del_driver(&adm1021_driver);
460
}
461
 
462
MODULE_AUTHOR ("Frodo Looijaard <frodol@dds.nl> and "
463
                "Philip Edelbrock <phil@netroedge.com>");
464
MODULE_DESCRIPTION("adm1021 driver");
465
MODULE_LICENSE("GPL");
466
 
467
module_param(read_only, bool, 0);
468
MODULE_PARM_DESC(read_only, "Don't set any values, read only mode");
469
 
470
module_init(sensors_adm1021_init)
471
module_exit(sensors_adm1021_exit)

powered by: WebSVN 2.1.0

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