Subversion Repositories shark

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
170 giacomo 1
/* ------------------------------------------------------------------------- */
2
/* i2c-algo-bit.c i2c driver algorithms for bit-shift adapters               */
3
/* ------------------------------------------------------------------------- */
4
/*   Copyright (C) 1995-2000 Simon G. Vogl
5
 
6
    This program is free software; you can redistribute it and/or modify
7
    it under the terms of the GNU General Public License as published by
8
    the Free Software Foundation; either version 2 of the License, or
9
    (at your option) any later version.
10
 
11
    This program is distributed in the hope that it will be useful,
12
    but WITHOUT ANY WARRANTY; without even the implied warranty of
13
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
    GNU General Public License for more details.
15
 
16
    You should have received a copy of the GNU General Public License
17
    along with this program; if not, write to the Free Software
18
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                */
19
/* ------------------------------------------------------------------------- */
20
 
21
/* SHARK version by Giacomo Guidi <giacomo@gandalf.sssup.it> */
22
 
23
#include <stdio.h>
24
#include <unistd.h>
25
 
26
#include <kernel/log.h>
27
 
28
#include "drivers/i2c.h"
29
#include "drivers/i2c-algo-bit.h"
30
 
31
/* ----- global defines ----------------------------------------------- */
32
 
33
#define udelay(x) usleep(x)
34
 
35
#define DEB(x) if (i2c_debug>=1) x;
36
#define DEB2(x) if (i2c_debug>=2) x;
37
#define DEBSTAT(x) if (i2c_debug>=3) x; /* print several statistical values*/
38
#define DEBPROTO(x) if (i2c_debug>=9) { x; }
39
        /* debug the protocol by showing transferred bits */
40
 
41
/* debugging - slow down transfer to have a look at the data ..         */
42
/* I use this with two leds&resistors, each one connected to sda,scl    */
43
/* respectively. This makes sure that the algorithm works. Some chips   */
44
/* might not like this, as they have an internal timeout of some mils   */
45
/*
46
#define SLO_IO      jif=jiffies;while(time_before_eq(jiffies, jif+i2c_table[minor].veryslow))\
47
                        if (need_resched) schedule();
48
*/
49
 
50
 
51
/* ----- global variables --------------------------------------------- */
52
 
53
#ifdef SLO_IO
54
        int jif;
55
#endif
56
 
57
/* module parameters:
58
 */
59
static int i2c_debug = 0;
60
static int bit_test = 0;        /* see if the line-setting functions work       */
61
static int bit_scan = 0;        /* have a look at what's hanging 'round         */
62
 
63
/* --- setting states on the bus with the right timing: --------------- */
64
 
65
#define setsda(adap,val) adap->setsda(adap->data, val)
66
#define setscl(adap,val) adap->setscl(adap->data, val)
67
#define getsda(adap) adap->getsda(adap->data)
68
#define getscl(adap) adap->getscl(adap->data)
69
 
70
static inline void sdalo(struct i2c_algo_bit_data *adap)
71
{
72
        setsda(adap,0);
73
        udelay(adap->udelay);
74
}
75
 
76
static inline void sdahi(struct i2c_algo_bit_data *adap)
77
{
78
        setsda(adap,1);
79
        udelay(adap->udelay);
80
 
81
 
82
}
83
 
84
static inline void scllo(struct i2c_algo_bit_data *adap)
85
{
86
        setscl(adap,0);
87
        udelay(adap->udelay);
88
#ifdef SLO_IO
89
        SLO_IO
90
#endif
91
}
92
 
93
/*
94
 * Raise scl line, and do checking for delays. This is necessary for slower
95
 * devices.
96
 */
97
static inline int sclhi(struct i2c_algo_bit_data *adap)
98
{
99
        setscl(adap,1);
100
 
101
        udelay(adap->udelay);
102
 
103
        /* Not all adapters have scl sense line... */
104
        if (adap->getscl == NULL )
105
                return 0;
106
 
107
        while (!getscl(adap)) {
108
                /* the hw knows how to read the clock line,
109
                 * so we wait until it actually gets high.
110
                 * This is safer as some chips may hold it low
111
                 * while they are processing data internally.
112
                 */
113
                setscl(adap,1);
114
        }
115
 
116
#ifdef SLO_IO
117
        SLO_IO
118
#endif
119
        return 0;
120
}
121
 
122
 
123
/* --- other auxiliary functions -------------------------------------- */
124
static void i2c_start(struct i2c_algo_bit_data *adap)
125
{
126
        /* assert: scl, sda are high */
127
        DEBPROTO(cprintf("S "));
128
        sdalo(adap);
129
        scllo(adap);
130
}
131
 
132
static void i2c_repstart(struct i2c_algo_bit_data *adap)
133
{
134
        /* scl, sda may not be high */
135
        DEBPROTO(cprintf(" Sr "));
136
        setsda(adap,1);
137
        setscl(adap,1);
138
        udelay(adap->udelay);
139
 
140
        sdalo(adap);
141
        scllo(adap);
142
}
143
 
144
 
145
static void i2c_stop(struct i2c_algo_bit_data *adap)
146
{
147
        DEBPROTO(cprintf("P\n"));
148
        /* assert: scl is low */
149
        sdalo(adap);
150
        sclhi(adap);
151
        sdahi(adap);
152
}
153
 
154
 
155
 
156
/* send a byte without start cond., look for arbitration,
157
   check ackn. from slave */
158
/* returns:
159
 * 1 if the device acknowledged
160
 * 0 if the device did not ack
161
 * -ETIMEDOUT if an error occurred (while raising the scl line)
162
 */
163
static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
164
{
165
        int i;
166
        int sb;
167
        int ack;
168
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
169
 
170
        /* assert: scl is low */
171
        DEB2(cprintf(" i2c_outb:%2x\n",c&0xff));
172
        for ( i=7 ; i>=0 ; i-- ) {
173
                sb = c & ( 1 << i );
174
                setsda(adap,sb);
175
                udelay(adap->udelay);
176
                DEBPROTO(cprintf("%d",sb!=0));
177
                if (sclhi(adap)<0) { /* timed out */
178
                        sdahi(adap); /* we don't want to block the net */
179
                        return -ETIMEDOUT;
180
                };
181
                /* do arbitration here:
182
                 * if ( sb && ! getsda(adap) ) -> ouch! Get out of here.
183
                 */
184
                setscl(adap, 0 );
185
                udelay(adap->udelay);
186
        }
187
        sdahi(adap);
188
        if (sclhi(adap)<0){ /* timeout */
189
                return -ETIMEDOUT;
190
        };
191
        /* read ack: SDA should be pulled down by slave */
192
        ack=getsda(adap);       /* ack: sda is pulled low ->success.     */
193
        DEB2(cprintf(" i2c_outb: getsda() =  0x%2x\n", ~ack ));
194
 
195
        DEBPROTO(cprintf("[%2x]",c&0xff) );
196
        DEBPROTO(if (0==ack){ cprintf(" A ");} else cprintf(" NA ") );
197
        scllo(adap);
198
        return 0==ack;          /* return 1 if device acked      */
199
        /* assert: scl is low (sda undef) */
200
}
201
 
202
 
203
static int i2c_inb(struct i2c_adapter *i2c_adap)
204
{
205
        /* read byte via i2c port, without start/stop sequence  */
206
        /* acknowledge is sent in i2c_read.                     */
207
        int i;
208
        unsigned char indata=0;
209
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
210
 
211
        /* assert: scl is low */
212
        DEB2(cprintf("i2c_inb.\n"));
213
 
214
        sdahi(adap);
215
        for (i=0;i<8;i++) {
216
                if (sclhi(adap)<0) { /* timeout */
217
                        return -ETIMEDOUT;
218
                };
219
                indata *= 2;
220
                if ( getsda(adap) )
221
                        indata |= 0x01;
222
                scllo(adap);
223
        }
224
        /* assert: scl is low */
225
        DEBPROTO(cprintf(" %2x", indata & 0xff));
226
        return (int) (indata & 0xff);
227
}
228
 
229
/*
230
 * Sanity check for the adapter hardware - check the reaction of
231
 * the bus lines only if it seems to be idle.
232
 */
233
static int test_bus(struct i2c_algo_bit_data *adap, char* name) {
234
        int scl,sda;
235
        sda=getsda(adap);
236
        if (adap->getscl==NULL) {
237
                cprintf("i2c-algo-bit.o: Warning: Adapter can't read from clock line - skipping test.\n");
238
                return 0;              
239
        }
240
        scl=getscl(adap);
241
        cprintf("i2c-algo-bit.o: Adapter: %s scl: %d  sda: %d -- testing...\n",
242
               name,getscl(adap),getsda(adap));
243
        if (!scl || !sda ) {
244
                cprintf("i2c-algo-bit.o: %s seems to be busy.\n",name);
245
                goto bailout;
246
        }
247
        sdalo(adap);
248
        cprintf("i2c-algo-bit.o:1 scl: %d  sda: %d \n",getscl(adap),
249
               getsda(adap));
250
        if ( 0 != getsda(adap) ) {
251
                cprintf("i2c-algo-bit.o: %s SDA stuck high!\n",name);
252
                sdahi(adap);
253
                goto bailout;
254
        }
255
        if ( 0 == getscl(adap) ) {
256
                cprintf("i2c-algo-bit.o: %s SCL unexpected low while pulling SDA low!\n",
257
                        name);
258
                goto bailout;
259
        }              
260
        sdahi(adap);
261
        cprintf("i2c-algo-bit.o:2 scl: %d  sda: %d \n",getscl(adap),
262
               getsda(adap));
263
        if ( 0 == getsda(adap) ) {
264
                cprintf("i2c-algo-bit.o: %s SDA stuck low!\n",name);
265
                sdahi(adap);
266
                goto bailout;
267
        }
268
        if ( 0 == getscl(adap) ) {
269
                cprintf("i2c-algo-bit.o: %s SCL unexpected low while SDA high!\n",
270
                       name);
271
        goto bailout;
272
        }
273
        scllo(adap);
274
        cprintf("i2c-algo-bit.o:3 scl: %d  sda: %d \n",getscl(adap),
275
               getsda(adap));
276
        if ( 0 != getscl(adap) ) {
277
                cprintf("i2c-algo-bit.o: %s SCL stuck high!\n",name);
278
                sclhi(adap);
279
                goto bailout;
280
        }
281
        if ( 0 == getsda(adap) ) {
282
                cprintf("i2c-algo-bit.o: %s SDA unexpected low while pulling SCL low!\n",
283
                        name);
284
                goto bailout;
285
        }
286
        sclhi(adap);
287
        cprintf("i2c-algo-bit.o:4 scl: %d  sda: %d \n",getscl(adap),
288
               getsda(adap));
289
        if ( 0 == getscl(adap) ) {
290
                cprintf("i2c-algo-bit.o: %s SCL stuck low!\n",name);
291
                sclhi(adap);
292
                goto bailout;
293
        }
294
        if ( 0 == getsda(adap) ) {
295
                cprintf("i2c-algo-bit.o: %s SDA unexpected low while SCL high!\n",
296
                        name);
297
                goto bailout;
298
        }
299
        cprintf("i2c-algo-bit.o: %s passed test.\n",name);
300
        return 0;
301
bailout:
302
        sdahi(adap);
303
        sclhi(adap);
304
        return -ENODEV;
305
}
306
 
307
/* ----- Utility functions
308
 */
309
 
310
/* try_address tries to contact a chip for a number of
311
 * times before it gives up.
312
 * return values:
313
 * 1 chip answered
314
 * 0 chip did not answer
315
 * -x transmission error
316
 */
317
static inline int try_address(struct i2c_adapter *i2c_adap,
318
                       unsigned char addr, int retries)
319
{
320
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
321
        int i,ret = -1;
322
        for (i=0;i<=retries;i++) {
323
                ret = i2c_outb(i2c_adap,addr);
324
                if (ret==1)
325
                        break;  /* success! */
326
                i2c_stop(adap);
327
                udelay(5/*adap->udelay*/);
328
                if (i==retries)  /* no success */
329
                        break;
330
                i2c_start(adap);
331
                udelay(adap->udelay);
332
        }
333
        DEB2(if (i) cprintf("i2c-algo-bit.o: needed %d retries for %d\n",
334
                           i,addr));
335
        return ret;
336
}
337
 
338
static int sendbytes(struct i2c_adapter *i2c_adap,const char *buf, int count)
339
{
340
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
341
        char c;
342
        const char *temp = buf;
343
        int retval;
344
        int wrcount=0;
345
 
346
        while (count > 0) {
347
                c = *temp;
348
                DEB2(cprintf("i2c-algo-bit.o: %s i2c_write: writing %2x\n",
349
                            i2c_adap->name, c&0xff));
350
                retval = i2c_outb(i2c_adap,c);
351
                if (retval>0) {
352
                        count--;
353
                        temp++;
354
                        wrcount++;
355
                } else { /* arbitration or no acknowledge */
356
                        cprintf("i2c-algo-bit.o: %s i2c_write: error - bailout.\n",
357
                               i2c_adap->name);
358
                        i2c_stop(adap);
359
                        return (retval<0)? retval : -EFAULT;
360
                                /* got a better one ?? */
361
                }
362
#if 0
363
                /* from asm/delay.h */
364
                __delay(adap->mdelay * (loops_per_sec / 1000) );
365
#endif
366
        }
367
        return wrcount;
368
}
369
 
370
static inline int readbytes(struct i2c_adapter *i2c_adap,char *buf,int count)
371
{
372
        char *temp = buf;
373
        int inval;
374
        int rdcount=0;          /* counts bytes read */
375
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
376
 
377
        while (count > 0) {
378
                inval = i2c_inb(i2c_adap);
379
                if (inval>=0) {
380
                        *temp = inval;
381
                        rdcount++;
382
                } else {   /* read timed out */
383
                        cprintf("i2c-algo-bit.o: i2c_read: i2c_inb timed out.\n");
384
                        break;
385
                }
386
 
387
                if ( count > 1 ) {              /* send ack */
388
                        sdalo(adap);
389
                        DEBPROTO(cprintf(" Am "));
390
                } else {
391
                        sdahi(adap);    /* neg. ack on last byte */
392
                        DEBPROTO(cprintf(" NAm "));
393
                }
394
                if (sclhi(adap)<0) {    /* timeout */
395
                        sdahi(adap);
396
                        cprintf("i2c-algo-bit.o: i2c_read: Timeout at ack\n");
397
                        return -ETIMEDOUT;
398
                };
399
                scllo(adap);
400
                sdahi(adap);
401
                temp++;
402
                count--;
403
        }
404
        return rdcount;
405
}
406
 
407
/* doAddress initiates the transfer by generating the start condition (in
408
 * try_address) and transmits the address in the necessary format to handle
409
 * reads, writes as well as 10bit-addresses.
410
 * returns:
411
 *  0 everything went okay, the chip ack'ed
412
 * -x an error occurred (like: -EREMOTEIO if the device did not answer, or
413
 *      -ETIMEDOUT, for example if the lines are stuck...)
414
 */
415
static inline int bit_doAddress(struct i2c_adapter *i2c_adap,
416
                                struct i2c_msg *msg, int retries)
417
{
418
        unsigned short flags = msg->flags;
419
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
420
 
421
        unsigned char addr;
422
        int ret;
423
        if ( (flags & I2C_M_TEN)  ) {
424
                /* a ten bit address */
425
                addr = 0xf0 | (( msg->addr >> 7) & 0x03);
426
                DEB2(cprintf("addr0: %d\n",addr));
427
                /* try extended address code...*/
428
                ret = try_address(i2c_adap, addr, retries);
429
                if (ret!=1) {
430
                        cprintf("died at extended address code.\n");
431
                        return -EREMOTEIO;
432
                }
433
                /* the remaining 8 bit address */
434
                ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
435
                if (ret != 1) {
436
                        /* the chip did not ack / xmission error occurred */
437
                        cprintf("died at 2nd address code.\n");
438
                        return -EREMOTEIO;
439
                }
440
                if ( flags & I2C_M_RD ) {
441
                        i2c_repstart(adap);
442
                        /* okay, now switch into reading mode */
443
                        addr |= 0x01;
444
                        ret = try_address(i2c_adap, addr, retries);
445
                        if (ret!=1) {
446
                                cprintf("died at extended address code.\n");
447
                                return -EREMOTEIO;
448
                        }
449
                }
450
        } else {                /* normal 7bit address  */
451
                addr = ( msg->addr << 1 );
452
                if (flags & I2C_M_RD )
453
                        addr |= 1;
454
                if (flags & I2C_M_REV_DIR_ADDR )
455
                        addr ^= 1;
456
                ret = try_address(i2c_adap, addr, retries);
457
                if (ret!=1) {
458
                        return -EREMOTEIO;
459
                }
460
        }
461
        return 0;
462
}
463
 
464
static int bit_xfer(struct i2c_adapter *i2c_adap,
465
                    struct i2c_msg msgs[], int num)
466
{
467
        struct i2c_msg *pmsg;
468
        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
469
 
470
        int i,ret;
471
 
472
        i2c_start(adap);
473
        for (i=0;i<num;i++) {
474
                pmsg = &msgs[i];
475
                if (!(pmsg->flags & I2C_M_NOSTART)) {
476
                        if (i) {
477
                                i2c_repstart(adap);
478
                        }
479
                        ret = bit_doAddress(i2c_adap,pmsg,i2c_adap->retries);
480
                        if (ret != 0) {
481
                                DEB2(cprintf("i2c-algo-bit.o: NAK from device adr %2x msg #%d\n"
482
                                       ,msgs[i].addr,i));
483
                                return (ret<0) ? ret : -EREMOTEIO;
484
                        }
485
                }
486
                if (pmsg->flags & I2C_M_RD ) {
487
                        /* read bytes into buffer*/
488
                        ret = readbytes(i2c_adap,pmsg->buf,pmsg->len);
489
                        DEB2(cprintf("i2c-algo-bit.o: read %d bytes.\n",ret));
490
                        if (ret < pmsg->len ) {
491
                                return (ret<0)? ret : -EREMOTEIO;
492
                        }
493
                } else {
494
                        /* write bytes from buffer */
495
                        ret = sendbytes(i2c_adap,pmsg->buf,pmsg->len);
496
                        DEB2(cprintf("i2c-algo-bit.o: wrote %d bytes.\n",ret));
497
                        if (ret < pmsg->len ) {
498
                                return (ret<0) ? ret : -EREMOTEIO;
499
                        }
500
                }
501
        }
502
        i2c_stop(adap);
503
        return num;
504
}
505
 
506
static int algo_control(struct i2c_adapter *adapter,
507
        unsigned int cmd, unsigned long arg)
508
{
509
        return 0;
510
}
511
 
512
static __u32 bit_func(struct i2c_adapter *adap)
513
{
514
        return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR |
515
               I2C_FUNC_PROTOCOL_MANGLING;
516
}
517
 
518
 
519
/* -----exported algorithm data: -------------------------------------  */
520
 
521
static struct i2c_algorithm i2c_bit_algo = {
522
        "Bit-shift algorithm",
523
        I2C_ALGO_BIT,
524
        bit_xfer,
525
        NULL,
526
        NULL,                           /* slave_xmit           */
527
        NULL,                           /* slave_recv           */
528
        algo_control,                   /* ioctl                */
529
        bit_func,                       /* functionality        */
530
};
531
 
532
/*
533
 * registering functions to load algorithms at runtime
534
 */
535
int i2c_bit_add_bus(struct i2c_adapter *adap)
536
{
537
        int i;
538
        struct i2c_algo_bit_data *bit_adap = adap->algo_data;
539
 
540
        if (bit_test) {
541
                int ret = test_bus(bit_adap, adap->name);
542
                if (ret<0)
543
                        return -ENODEV;
544
        }
545
 
546
        DEB2(cprintf("i2c-algo-bit.o: hw routines for %s registered.\n",
547
                    adap->name));
548
 
549
        /* register new adapter to i2c module... */
550
 
551
        adap->id |= i2c_bit_algo.id;
552
        adap->algo = &i2c_bit_algo;
553
 
554
        adap->timeout = 100;    /* default values, should       */
555
        adap->retries = 3;      /* be replaced by defines       */
556
 
557
        /* scan bus */
558
        if (bit_scan) {
559
                int ack;
560
                cprintf("i2c-algo-bit.o: scanning bus %s.\n",
561
                       adap->name);
562
                for (i = 0x00; i < 0xff; i+=2) {
563
                        i2c_start(bit_adap);
564
                        ack = i2c_outb(adap,i);
565
                        i2c_stop(bit_adap);
566
                        if (ack>0) {
567
                                cprintf("(%2x) \n",i>>1);
568
                        } else
569
                                cprintf(". ");
570
                        sleep(3);
571
                }
572
                cprintf("\n");
573
        }
574
 
575
#ifdef MODULE
576
        MOD_INC_USE_COUNT;
577
#endif
578
        i2c_add_adapter(adap);
579
 
580
        return 0;
581
}
582
 
583
 
584
int i2c_bit_del_bus(struct i2c_adapter *adap)
585
{
586
        int res;
587
 
588
        if ((res = i2c_del_adapter(adap)) < 0)
589
                return res;
590
 
591
        DEB2(cprintf("i2c-algo-bit.o: adapter unregistered: %s\n",adap->name));
592
 
593
#ifdef MODULE
594
        MOD_DEC_USE_COUNT;
595
#endif
596
        return 0;
597
}
598
 
599
int i2c_algo_bit_init (void)
600
{
601
        printk(KERN_INFO "i2c-algo-bit.o: i2c bit algorithm module\n");
602
        return 0;
603
}
604