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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [drivers/] [i2c/] [i2c-proc.c] - Blame information for rev 1774

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

Line No. Rev Author Line
1 1275 phoenix
/*
2
    i2c-proc.c - Part of lm_sensors, Linux kernel modules for hardware
3
                monitoring
4
    Copyright (c) 1998 - 2001 Frodo Looijaard <frodol@dds.nl> and
5
    Mark D. Studebaker <mdsxyz123@yahoo.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
/*
23
    This driver puts entries in /proc/sys/dev/sensors for each I2C device
24
*/
25
 
26
#include <linux/module.h>
27
#include <linux/kernel.h>
28
#include <linux/slab.h>
29
#include <linux/ctype.h>
30
#include <linux/sysctl.h>
31
#include <linux/proc_fs.h>
32
#include <linux/ioport.h>
33
#include <asm/uaccess.h>
34
 
35
#include <linux/i2c.h>
36
#include <linux/i2c-proc.h>
37
 
38
#include <linux/init.h>
39
 
40
#ifndef THIS_MODULE
41
#define THIS_MODULE NULL
42
#endif
43
 
44
static int i2c_create_name(char **name, const char *prefix,
45
                               struct i2c_adapter *adapter, int addr);
46
static int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
47
                               long *results, int magnitude);
48
static int i2c_write_reals(int nrels, void *buffer, int *bufsize,
49
                               long *results, int magnitude);
50
static int i2c_proc_chips(ctl_table * ctl, int write,
51
                              struct file *filp, void *buffer,
52
                              size_t * lenp);
53
static int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
54
                                void *oldval, size_t * oldlenp,
55
                                void *newval, size_t newlen,
56
                                void **context);
57
 
58
int __init sensors_init(void);
59
 
60
#define SENSORS_ENTRY_MAX 20
61
static struct ctl_table_header *i2c_entries[SENSORS_ENTRY_MAX];
62
 
63
static struct i2c_client *i2c_clients[SENSORS_ENTRY_MAX];
64
static unsigned short i2c_inodes[SENSORS_ENTRY_MAX];
65
 
66
static ctl_table sysctl_table[] = {
67
        {CTL_DEV, "dev", NULL, 0, 0555},
68
        {0},
69
        {DEV_SENSORS, "sensors", NULL, 0, 0555},
70
        {0},
71
        {0, NULL, NULL, 0, 0555},
72
        {0}
73
};
74
 
75
static ctl_table i2c_proc_dev_sensors[] = {
76
        {SENSORS_CHIPS, "chips", NULL, 0, 0644, NULL, &i2c_proc_chips,
77
         &i2c_sysctl_chips},
78
        {0}
79
};
80
 
81
static ctl_table i2c_proc_dev[] = {
82
        {DEV_SENSORS, "sensors", NULL, 0, 0555, i2c_proc_dev_sensors},
83
        {0},
84
};
85
 
86
 
87
static ctl_table i2c_proc[] = {
88
        {CTL_DEV, "dev", NULL, 0, 0555, i2c_proc_dev},
89
        {0}
90
};
91
 
92
 
93
static struct ctl_table_header *i2c_proc_header;
94
static int i2c_initialized;
95
 
96
/* This returns a nice name for a new directory; for example lm78-isa-0310
97
   (for a LM78 chip on the ISA bus at port 0x310), or lm75-i2c-3-4e (for
98
   a LM75 chip on the third i2c bus at address 0x4e).
99
   name is allocated first. */
100
int i2c_create_name(char **name, const char *prefix,
101
                        struct i2c_adapter *adapter, int addr)
102
{
103
        char name_buffer[50];
104
        int id;
105
        if (i2c_is_isa_adapter(adapter))
106
                sprintf(name_buffer, "%s-isa-%04x", prefix, addr);
107
        else {
108
                if ((id = i2c_adapter_id(adapter)) < 0)
109
                        return -ENOENT;
110
                sprintf(name_buffer, "%s-i2c-%d-%02x", prefix, id, addr);
111
        }
112
        *name = kmalloc(strlen(name_buffer) + 1, GFP_KERNEL);
113
        if (!*name) {
114
                printk (KERN_WARNING "i2c_create_name: not enough memory\n");
115
                return -ENOMEM;
116
        }
117
        strcpy(*name, name_buffer);
118
        return 0;
119
}
120
 
121
/* This rather complex function must be called when you want to add an entry
122
   to /proc/sys/dev/sensors/chips. It also creates a new directory within
123
   /proc/sys/dev/sensors/.
124
   ctl_template should be a template of the newly created directory. It is
125
   copied in memory. The extra2 field of each file is set to point to client.
126
   If any driver wants subdirectories within the newly created directory,
127
   this function must be updated!
128
   controlling_mod is the controlling module. It should usually be
129
   THIS_MODULE when calling. Note that this symbol is not defined in
130
   kernels before 2.3.13; define it to NULL in that case. We will not use it
131
   for anything older than 2.3.27 anyway. */
132
int i2c_register_entry(struct i2c_client *client, const char *prefix,
133
                           ctl_table * ctl_template,
134
                           struct module *controlling_mod)
135
{
136
        int i, res, len, id;
137
        ctl_table *new_table;
138
        char *name;
139
        struct ctl_table_header *new_header;
140
 
141
        if ((res = i2c_create_name(&name, prefix, client->adapter,
142
                                       client->addr))) return res;
143
 
144
        for (id = 0; id < SENSORS_ENTRY_MAX; id++)
145
                if (!i2c_entries[id]) {
146
                        break;
147
                }
148
        if (id == SENSORS_ENTRY_MAX) {
149
                kfree(name);
150
                return -ENOMEM;
151
        }
152
        id += 256;
153
 
154
        len = 0;
155
        while (ctl_template[len].procname)
156
                len++;
157
        len += 7;
158
        if (!(new_table = kmalloc(sizeof(ctl_table) * len, GFP_KERNEL))) {
159
                kfree(name);
160
                return -ENOMEM;
161
        }
162
 
163
        memcpy(new_table, sysctl_table, 6 * sizeof(ctl_table));
164
        new_table[0].child = &new_table[2];
165
        new_table[2].child = &new_table[4];
166
        new_table[4].child = &new_table[6];
167
        new_table[4].procname = name;
168
        new_table[4].ctl_name = id;
169
        memcpy(new_table + 6, ctl_template, (len - 6) * sizeof(ctl_table));
170
        for (i = 6; i < len; i++)
171
                new_table[i].extra2 = client;
172
 
173
        if (!(new_header = register_sysctl_table(new_table, 0))) {
174
                kfree(new_table);
175
                kfree(name);
176
                return -ENOMEM;
177
        }
178
 
179
        i2c_entries[id - 256] = new_header;
180
 
181
        i2c_clients[id - 256] = client;
182
#ifdef DEBUG
183
        if (!new_header || !new_header->ctl_table ||
184
            !new_header->ctl_table->child ||
185
            !new_header->ctl_table->child->child ||
186
            !new_header->ctl_table->child->child->de) {
187
                printk
188
                    ("i2c-proc.o: NULL pointer when trying to install fill_inode fix!\n");
189
                return id;
190
        }
191
#endif                          /* DEBUG */
192
        i2c_inodes[id - 256] =
193
            new_header->ctl_table->child->child->de->low_ino;
194
        new_header->ctl_table->child->child->de->owner = controlling_mod;
195
 
196
        return id;
197
}
198
 
199
void i2c_deregister_entry(int id)
200
{
201
        ctl_table *table;
202
        char *temp;
203
        id -= 256;
204
        if (i2c_entries[id]) {
205
                table = i2c_entries[id]->ctl_table;
206
                unregister_sysctl_table(i2c_entries[id]);
207
                /* 2-step kfree needed to keep gcc happy about const points */
208
                (const char *) temp = table[4].procname;
209
                kfree(temp);
210
                kfree(table);
211
                i2c_entries[id] = NULL;
212
                i2c_clients[id] = NULL;
213
        }
214
}
215
 
216
/* Monitor access for /proc/sys/dev/sensors; make unloading i2c-proc.o
217
   impossible if some process still uses it or some file in it */
218
void i2c_fill_inode(struct inode *inode, int fill)
219
{
220
        if (fill)
221
                MOD_INC_USE_COUNT;
222
        else
223
                MOD_DEC_USE_COUNT;
224
}
225
 
226
/* Monitor access for /proc/sys/dev/sensors/ directories; make unloading
227
   the corresponding module impossible if some process still uses it or
228
   some file in it */
229
void i2c_dir_fill_inode(struct inode *inode, int fill)
230
{
231
        int i;
232
        struct i2c_client *client;
233
 
234
#ifdef DEBUG
235
        if (!inode) {
236
                printk("i2c-proc.o: Warning: inode NULL in fill_inode()\n");
237
                return;
238
        }
239
#endif                          /* def DEBUG */
240
 
241
        for (i = 0; i < SENSORS_ENTRY_MAX; i++)
242
                if (i2c_clients[i]
243
                    && (i2c_inodes[i] == inode->i_ino)) break;
244
#ifdef DEBUG
245
        if (i == SENSORS_ENTRY_MAX) {
246
                printk
247
                    ("i2c-proc.o: Warning: inode (%ld) not found in fill_inode()\n",
248
                     inode->i_ino);
249
                return;
250
        }
251
#endif                          /* def DEBUG */
252
        client = i2c_clients[i];
253
        if (fill)
254
                client->driver->inc_use(client);
255
        else
256
                client->driver->dec_use(client);
257
}
258
 
259
int i2c_proc_chips(ctl_table * ctl, int write, struct file *filp,
260
                       void *buffer, size_t * lenp)
261
{
262
        char BUF[SENSORS_PREFIX_MAX + 30];
263
        int buflen, curbufsize, i;
264
        struct ctl_table *client_tbl;
265
 
266
        if (write)
267
                return 0;
268
 
269
        /* If buffer is size 0, or we try to read when not at the start, we
270
           return nothing. Note that I think writing when not at the start
271
           does not work either, but anyway, this is straight from the kernel
272
           sources. */
273
        if (!*lenp || (filp->f_pos && !write)) {
274
                *lenp = 0;
275
                return 0;
276
        }
277
        curbufsize = 0;
278
        for (i = 0; i < SENSORS_ENTRY_MAX; i++)
279
                if (i2c_entries[i]) {
280
                        client_tbl =
281
                            i2c_entries[i]->ctl_table->child->child;
282
                        buflen =
283
                            sprintf(BUF, "%d\t%s\n", client_tbl->ctl_name,
284
                                    client_tbl->procname);
285
                        if (buflen + curbufsize > *lenp)
286
                                buflen = *lenp - curbufsize;
287
                        if(copy_to_user(buffer, BUF, buflen))
288
                                return -EFAULT;
289
                        curbufsize += buflen;
290
                        (char *) buffer += buflen;
291
                }
292
        *lenp = curbufsize;
293
        filp->f_pos += curbufsize;
294
        return 0;
295
}
296
 
297
int i2c_sysctl_chips(ctl_table * table, int *name, int nlen,
298
                         void *oldval, size_t * oldlenp, void *newval,
299
                         size_t newlen, void **context)
300
{
301
        struct i2c_chips_data data;
302
        int i, oldlen, nrels, maxels,ret=0;
303
        struct ctl_table *client_tbl;
304
 
305
        if (oldval && oldlenp && !((ret = get_user(oldlen, oldlenp))) &&
306
            oldlen) {
307
                maxels = oldlen / sizeof(struct i2c_chips_data);
308
                nrels = 0;
309
                for (i = 0; (i < SENSORS_ENTRY_MAX) && (nrels < maxels);
310
                     i++)
311
                        if (i2c_entries[i]) {
312
                                client_tbl =
313
                                    i2c_entries[i]->ctl_table->child->
314
                                    child;
315
                                data.sysctl_id = client_tbl->ctl_name;
316
                                strcpy(data.name, client_tbl->procname);
317
                                if(copy_to_user(oldval, &data,
318
                                             sizeof(struct
319
                                                    i2c_chips_data)))
320
                                        return -EFAULT;
321
                                (char *) oldval +=
322
                                    sizeof(struct i2c_chips_data);
323
                                nrels++;
324
                        }
325
                oldlen = nrels * sizeof(struct i2c_chips_data);
326
                if(put_user(oldlen, oldlenp))
327
                        return -EFAULT;
328
        }
329
        return ret;
330
}
331
 
332
 
333
/* This funcion reads or writes a 'real' value (encoded by the combination
334
   of an integer and a magnitude, the last is the power of ten the value
335
   should be divided with) to a /proc/sys directory. To use this function,
336
   you must (before registering the ctl_table) set the extra2 field to the
337
   client, and the extra1 field to a function of the form:
338
      void func(struct i2c_client *client, int operation, int ctl_name,
339
                int *nrels_mag, long *results)
340
   This function can be called for three values of operation. If operation
341
   equals SENSORS_PROC_REAL_INFO, the magnitude should be returned in
342
   nrels_mag. If operation equals SENSORS_PROC_REAL_READ, values should
343
   be read into results. nrels_mag should return the number of elements
344
   read; the maximum number is put in it on entry. Finally, if operation
345
   equals SENSORS_PROC_REAL_WRITE, the values in results should be
346
   written to the chip. nrels_mag contains on entry the number of elements
347
   found.
348
   In all cases, client points to the client we wish to interact with,
349
   and ctl_name is the SYSCTL id of the file we are accessing. */
350
int i2c_proc_real(ctl_table * ctl, int write, struct file *filp,
351
                      void *buffer, size_t * lenp)
352
{
353
#define MAX_RESULTS 32
354
        int mag, nrels = MAX_RESULTS;
355
        long results[MAX_RESULTS];
356
        i2c_real_callback callback = ctl->extra1;
357
        struct i2c_client *client = ctl->extra2;
358
        int res;
359
 
360
        /* If buffer is size 0, or we try to read when not at the start, we
361
           return nothing. Note that I think writing when not at the start
362
           does not work either, but anyway, this is straight from the kernel
363
           sources. */
364
        if (!*lenp || (filp->f_pos && !write)) {
365
                *lenp = 0;
366
                return 0;
367
        }
368
 
369
        /* Get the magnitude */
370
        callback(client, SENSORS_PROC_REAL_INFO, ctl->ctl_name, &mag,
371
                 NULL);
372
 
373
        if (write) {
374
                /* Read the complete input into results, converting to longs */
375
                res = i2c_parse_reals(&nrels, buffer, *lenp, results, mag);
376
                if (res)
377
                        return res;
378
 
379
                if (!nrels)
380
                        return 0;
381
 
382
                /* Now feed this information back to the client */
383
                callback(client, SENSORS_PROC_REAL_WRITE, ctl->ctl_name,
384
                         &nrels, results);
385
 
386
                filp->f_pos += *lenp;
387
                return 0;
388
        } else {                /* read */
389
                /* Get the information from the client into results */
390
                callback(client, SENSORS_PROC_REAL_READ, ctl->ctl_name,
391
                         &nrels, results);
392
 
393
                /* And write them to buffer, converting to reals */
394
                res = i2c_write_reals(nrels, buffer, lenp, results, mag);
395
                if (res)
396
                        return res;
397
                filp->f_pos += *lenp;
398
                return 0;
399
        }
400
}
401
 
402
/* This function is equivalent to i2c_proc_real, only it interacts with
403
   the sysctl(2) syscall, and returns no reals, but integers */
404
int i2c_sysctl_real(ctl_table * table, int *name, int nlen,
405
                        void *oldval, size_t * oldlenp, void *newval,
406
                        size_t newlen, void **context)
407
{
408
        long results[MAX_RESULTS];
409
        int oldlen, nrels = MAX_RESULTS,ret=0;
410
        i2c_real_callback callback = table->extra1;
411
        struct i2c_client *client = table->extra2;
412
 
413
        /* Check if we need to output the old values */
414
        if (oldval && oldlenp && !((ret=get_user(oldlen, oldlenp))) && oldlen) {
415
                callback(client, SENSORS_PROC_REAL_READ, table->ctl_name,
416
                         &nrels, results);
417
 
418
                /* Note the rounding factor! */
419
                if (nrels * sizeof(long) < oldlen)
420
                        oldlen = nrels * sizeof(long);
421
                oldlen = (oldlen / sizeof(long)) * sizeof(long);
422
                if(copy_to_user(oldval, results, oldlen))
423
                        return -EFAULT;
424
                if(put_user(oldlen, oldlenp))
425
                        return -EFAULT;
426
        }
427
 
428
        if (newval && newlen) {
429
                /* Note the rounding factor! */
430
                newlen -= newlen % sizeof(long);
431
                nrels = newlen / sizeof(long);
432
                if(copy_from_user(results, newval, newlen))
433
                        return -EFAULT;
434
 
435
                /* Get the new values back to the client */
436
                callback(client, SENSORS_PROC_REAL_WRITE, table->ctl_name,
437
                         &nrels, results);
438
        }
439
        return ret;
440
}
441
 
442
 
443
/* nrels contains initially the maximum number of elements which can be
444
   put in results, and finally the number of elements actually put there.
445
   A magnitude of 1 will multiply everything with 10; etc.
446
   buffer, bufsize is the character buffer we read from and its length.
447
   results will finally contain the parsed integers.
448
 
449
   Buffer should contain several reals, separated by whitespace. A real
450
   has the following syntax:
451
     [ Minus ] Digit* [ Dot Digit* ]
452
   (everything between [] is optional; * means zero or more).
453
   When the next character is unparsable, everything is skipped until the
454
   next whitespace.
455
 
456
   WARNING! This is tricky code. I have tested it, but there may still be
457
            hidden bugs in it, even leading to crashes and things!
458
*/
459
int i2c_parse_reals(int *nrels, void *buffer, int bufsize,
460
                         long *results, int magnitude)
461
{
462
        int maxels, min, mag;
463
        long res,ret=0;
464
        char nextchar = 0;
465
 
466
        maxels = *nrels;
467
        *nrels = 0;
468
 
469
        while (bufsize && (*nrels < maxels)) {
470
 
471
                /* Skip spaces at the start */
472
                while (bufsize &&
473
                       !((ret=get_user(nextchar, (char *) buffer))) &&
474
                       isspace((int) nextchar)) {
475
                        bufsize--;
476
                        ((char *) buffer)++;
477
                }
478
 
479
                if (ret)
480
                        return -EFAULT;
481
                /* Well, we may be done now */
482
                if (!bufsize)
483
                        return 0;
484
 
485
                /* New defaults for our result */
486
                min = 0;
487
                res = 0;
488
                mag = magnitude;
489
 
490
                /* Check for a minus */
491
                if (!((ret=get_user(nextchar, (char *) buffer)))
492
                    && (nextchar == '-')) {
493
                        min = 1;
494
                        bufsize--;
495
                        ((char *) buffer)++;
496
                }
497
                if (ret)
498
                        return -EFAULT;
499
 
500
                /* Digits before a decimal dot */
501
                while (bufsize &&
502
                       !((ret=get_user(nextchar, (char *) buffer))) &&
503
                       isdigit((int) nextchar)) {
504
                        res = res * 10 + nextchar - '0';
505
                        bufsize--;
506
                        ((char *) buffer)++;
507
                }
508
                if (ret)
509
                        return -EFAULT;
510
 
511
                /* If mag < 0, we must actually divide here! */
512
                while (mag < 0) {
513
                        res = res / 10;
514
                        mag++;
515
                }
516
 
517
                if (bufsize && (nextchar == '.')) {
518
                        /* Skip the dot */
519
                        bufsize--;
520
                        ((char *) buffer)++;
521
 
522
                        /* Read digits while they are significant */
523
                        while (bufsize && (mag > 0) &&
524
                               !((ret=get_user(nextchar, (char *) buffer))) &&
525
                               isdigit((int) nextchar)) {
526
                                res = res * 10 + nextchar - '0';
527
                                mag--;
528
                                bufsize--;
529
                                ((char *) buffer)++;
530
                        }
531
                        if (ret)
532
                                return -EFAULT;
533
                }
534
                /* If we are out of data, but mag > 0, we need to scale here */
535
                while (mag > 0) {
536
                        res = res * 10;
537
                        mag--;
538
                }
539
 
540
                /* Skip everything until we hit whitespace */
541
                while (bufsize &&
542
                       !((ret=get_user(nextchar, (char *) buffer))) &&
543
                       isspace((int) nextchar)) {
544
                        bufsize--;
545
                        ((char *) buffer)++;
546
                }
547
                if (ret)
548
                        return -EFAULT;
549
 
550
                /* Put res in results */
551
                results[*nrels] = (min ? -1 : 1) * res;
552
                (*nrels)++;
553
        }
554
 
555
        /* Well, there may be more in the buffer, but we need no more data.
556
           Ignore anything that is left. */
557
        return 0;
558
}
559
 
560
int i2c_write_reals(int nrels, void *buffer, int *bufsize,
561
                         long *results, int magnitude)
562
{
563
#define BUFLEN 20
564
        char BUF[BUFLEN + 1];   /* An individual representation should fit! */
565
        char printfstr[10];
566
        int nr = 0;
567
        int buflen, mag, times;
568
        int curbufsize = 0;
569
 
570
        while ((nr < nrels) && (curbufsize < *bufsize)) {
571
                mag = magnitude;
572
 
573
                if (nr != 0) {
574
                        if(put_user(' ', (char *) buffer))
575
                                return -EFAULT;
576
                        curbufsize++;
577
                        ((char *) buffer)++;
578
                }
579
 
580
                /* Fill BUF with the representation of the next string */
581
                if (mag <= 0) {
582
                        buflen = sprintf(BUF, "%ld", results[nr]);
583
                        if (buflen < 0) {        /* Oops, a sprintf error! */
584
                                *bufsize = 0;
585
                                return -EINVAL;
586
                        }
587
                        while ((mag < 0) && (buflen < BUFLEN)) {
588
                                BUF[buflen++] = '0';
589
                                mag++;
590
                        }
591
                        BUF[buflen] = 0;
592
                } else {
593
                        times = 1;
594
                        for (times = 1; mag-- > 0; times *= 10);
595
                        if (results[nr] < 0) {
596
                                BUF[0] = '-';
597
                                buflen = 1;
598
                        } else
599
                                buflen = 0;
600
                        strcpy(printfstr, "%ld.%0Xld");
601
                        printfstr[6] = magnitude + '0';
602
                        buflen +=
603
                            sprintf(BUF + buflen, printfstr,
604
                                    abs(results[nr]) / times,
605
                                    abs(results[nr]) % times);
606
                        if (buflen < 0) {        /* Oops, a sprintf error! */
607
                                *bufsize = 0;
608
                                return -EINVAL;
609
                        }
610
                }
611
 
612
                /* Now copy it to the user-space buffer */
613
                if (buflen + curbufsize > *bufsize)
614
                        buflen = *bufsize - curbufsize;
615
                if(copy_to_user(buffer, BUF, buflen))
616
                        return -EFAULT;
617
                curbufsize += buflen;
618
                (char *) buffer += buflen;
619
 
620
                nr++;
621
        }
622
        if (curbufsize < *bufsize) {
623
                if(put_user('\n', (char *) buffer))
624
                        return -EFAULT;
625
                curbufsize++;
626
        }
627
        *bufsize = curbufsize;
628
        return 0;
629
}
630
 
631
 
632
/* Very inefficient for ISA detects, and won't work for 10-bit addresses! */
633
int i2c_detect(struct i2c_adapter *adapter,
634
                   struct i2c_address_data *address_data,
635
                   i2c_found_addr_proc * found_proc)
636
{
637
        int addr, i, found, j, err;
638
        struct i2c_force_data *this_force;
639
        int is_isa = i2c_is_isa_adapter(adapter);
640
        int adapter_id =
641
            is_isa ? SENSORS_ISA_BUS : i2c_adapter_id(adapter);
642
 
643
        /* Forget it if we can't probe using SMBUS_QUICK */
644
        if ((!is_isa)
645
            && !i2c_check_functionality(adapter,
646
                                        I2C_FUNC_SMBUS_QUICK)) return -1;
647
 
648
        for (addr = 0x00; addr <= (is_isa ? 0xffff : 0x7f); addr++) {
649
                if ((is_isa && check_region(addr, 1)) ||
650
                    (!is_isa && i2c_check_addr(adapter, addr)))
651
                        continue;
652
 
653
                /* If it is in one of the force entries, we don't do any
654
                   detection at all */
655
                found = 0;
656
                for (i = 0;
657
                     !found
658
                     && (this_force =
659
                         address_data->forces + i, this_force->force); i++) {
660
                        for (j = 0;
661
                             !found
662
                             && (this_force->force[j] != SENSORS_I2C_END);
663
                             j += 2) {
664
                                if (
665
                                    ((adapter_id == this_force->force[j])
666
                                     ||
667
                                     ((this_force->
668
                                       force[j] == SENSORS_ANY_I2C_BUS)
669
                                      && !is_isa))
670
                                    && (addr == this_force->force[j + 1])) {
671
#ifdef DEBUG
672
                                        printk
673
                                            (KERN_DEBUG "i2c-proc.o: found force parameter for adapter %d, addr %04x\n",
674
                                             adapter_id, addr);
675
#endif
676
                                        if (
677
                                            (err =
678
                                             found_proc(adapter, addr, 0,
679
                                                        this_force->
680
                                                        kind))) return err;
681
                                        found = 1;
682
                                }
683
                        }
684
                }
685
                if (found)
686
                        continue;
687
 
688
                /* If this address is in one of the ignores, we can forget about it
689
                   right now */
690
                for (i = 0;
691
                     !found
692
                     && (address_data->ignore[i] != SENSORS_I2C_END);
693
                     i += 2) {
694
                        if (
695
                            ((adapter_id == address_data->ignore[i])
696
                             ||
697
                             ((address_data->
698
                               ignore[i] == SENSORS_ANY_I2C_BUS)
699
                              && !is_isa))
700
                            && (addr == address_data->ignore[i + 1])) {
701
#ifdef DEBUG
702
                                printk
703
                                    (KERN_DEBUG "i2c-proc.o: found ignore parameter for adapter %d, "
704
                                     "addr %04x\n", adapter_id, addr);
705
#endif
706
                                found = 1;
707
                        }
708
                }
709
                for (i = 0;
710
                     !found
711
                     && (address_data->ignore_range[i] != SENSORS_I2C_END);
712
                     i += 3) {
713
                        if (
714
                            ((adapter_id == address_data->ignore_range[i])
715
                             ||
716
                             ((address_data->
717
                               ignore_range[i] ==
718
                               SENSORS_ANY_I2C_BUS) && !is_isa))
719
                            && (addr >= address_data->ignore_range[i + 1])
720
                            && (addr <= address_data->ignore_range[i + 2])) {
721
#ifdef DEBUG
722
                                printk
723
                                    (KERN_DEBUG "i2c-proc.o: found ignore_range parameter for adapter %d, "
724
                                     "addr %04x\n", adapter_id, addr);
725
#endif
726
                                found = 1;
727
                        }
728
                }
729
                if (found)
730
                        continue;
731
 
732
                /* Now, we will do a detection, but only if it is in the normal or
733
                   probe entries */
734
                if (is_isa) {
735
                        for (i = 0;
736
                             !found
737
                             && (address_data->normal_isa[i] !=
738
                                 SENSORS_ISA_END); i += 1) {
739
                                if (addr == address_data->normal_isa[i]) {
740
#ifdef DEBUG
741
                                        printk
742
                                            (KERN_DEBUG "i2c-proc.o: found normal isa entry for adapter %d, "
743
                                             "addr %04x\n", adapter_id,
744
                                             addr);
745
#endif
746
                                        found = 1;
747
                                }
748
                        }
749
                        for (i = 0;
750
                             !found
751
                             && (address_data->normal_isa_range[i] !=
752
                                 SENSORS_ISA_END); i += 3) {
753
                                if ((addr >=
754
                                     address_data->normal_isa_range[i])
755
                                    && (addr <=
756
                                        address_data->normal_isa_range[i + 1])
757
                                    &&
758
                                    ((addr -
759
                                      address_data->normal_isa_range[i]) %
760
                                     address_data->normal_isa_range[i + 2] ==
761
                                     0)) {
762
#ifdef DEBUG
763
                                        printk
764
                                            (KERN_DEBUG "i2c-proc.o: found normal isa_range entry for adapter %d, "
765
                                             "addr %04x", adapter_id, addr);
766
#endif
767
                                        found = 1;
768
                                }
769
                        }
770
                } else {
771
                        for (i = 0;
772
                             !found && (address_data->normal_i2c[i] !=
773
                                 SENSORS_I2C_END); i += 1) {
774
                                if (addr == address_data->normal_i2c[i]) {
775
                                        found = 1;
776
#ifdef DEBUG
777
                                        printk
778
                                            (KERN_DEBUG "i2c-proc.o: found normal i2c entry for adapter %d, "
779
                                             "addr %02x", adapter_id, addr);
780
#endif
781
                                }
782
                        }
783
                        for (i = 0;
784
                             !found
785
                             && (address_data->normal_i2c_range[i] !=
786
                                 SENSORS_I2C_END); i += 2) {
787
                                if ((addr >=
788
                                     address_data->normal_i2c_range[i])
789
                                    && (addr <=
790
                                        address_data->normal_i2c_range[i + 1]))
791
                                {
792
#ifdef DEBUG
793
                                        printk
794
                                            (KERN_DEBUG "i2c-proc.o: found normal i2c_range entry for adapter %d, "
795
                                             "addr %04x\n", adapter_id, addr);
796
#endif
797
                                        found = 1;
798
                                }
799
                        }
800
                }
801
 
802
                for (i = 0;
803
                     !found && (address_data->probe[i] != SENSORS_I2C_END);
804
                     i += 2) {
805
                        if (((adapter_id == address_data->probe[i]) ||
806
                             ((address_data->
807
                               probe[i] == SENSORS_ANY_I2C_BUS) && !is_isa))
808
                            && (addr == address_data->probe[i + 1])) {
809
#ifdef DEBUG
810
                                printk
811
                                    (KERN_DEBUG "i2c-proc.o: found probe parameter for adapter %d, "
812
                                     "addr %04x\n", adapter_id, addr);
813
#endif
814
                                found = 1;
815
                        }
816
                }
817
                for (i = 0; !found &&
818
                           (address_data->probe_range[i] != SENSORS_I2C_END);
819
                     i += 3) {
820
                        if (
821
                            ((adapter_id == address_data->probe_range[i])
822
                             ||
823
                             ((address_data->probe_range[i] ==
824
                               SENSORS_ANY_I2C_BUS) && !is_isa))
825
                            && (addr >= address_data->probe_range[i + 1])
826
                            && (addr <= address_data->probe_range[i + 2])) {
827
                                found = 1;
828
#ifdef DEBUG
829
                                printk
830
                                    (KERN_DEBUG "i2c-proc.o: found probe_range parameter for adapter %d, "
831
                                     "addr %04x\n", adapter_id, addr);
832
#endif
833
                        }
834
                }
835
                if (!found)
836
                        continue;
837
 
838
                /* OK, so we really should examine this address. First check
839
                   whether there is some client here at all! */
840
                if (is_isa ||
841
                    (i2c_smbus_xfer
842
                     (adapter, addr, 0, 0, 0, I2C_SMBUS_QUICK, NULL) >= 0))
843
                        if ((err = found_proc(adapter, addr, 0, -1)))
844
                                return err;
845
        }
846
        return 0;
847
}
848
 
849
int __init sensors_init(void)
850
{
851
        printk(KERN_INFO "i2c-proc.o version %s (%s)\n", I2C_VERSION, I2C_DATE);
852
        i2c_initialized = 0;
853
        if (!
854
            (i2c_proc_header =
855
             register_sysctl_table(i2c_proc, 0))) return -ENOMEM;
856
        i2c_proc_header->ctl_table->child->de->owner = THIS_MODULE;
857
        i2c_initialized++;
858
        return 0;
859
}
860
 
861
EXPORT_SYMBOL(i2c_deregister_entry);
862
EXPORT_SYMBOL(i2c_detect);
863
EXPORT_SYMBOL(i2c_proc_real);
864
EXPORT_SYMBOL(i2c_register_entry);
865
EXPORT_SYMBOL(i2c_sysctl_real);
866
 
867
#ifdef MODULE
868
 
869
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
870
MODULE_DESCRIPTION("i2c-proc driver");
871
MODULE_LICENSE("GPL");
872
 
873
int i2c_cleanup(void)
874
{
875
        if (i2c_initialized >= 1) {
876
                unregister_sysctl_table(i2c_proc_header);
877
                i2c_initialized--;
878
        }
879
        return 0;
880
}
881
 
882
int init_module(void)
883
{
884
        return sensors_init();
885
}
886
 
887
int cleanup_module(void)
888
{
889
        return i2c_cleanup();
890
}
891
#endif                          /* MODULE */

powered by: WebSVN 2.1.0

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