root/i2c/trunk/kernel/i2c-algo-bit.c @ 3765

Revision 3765, 15.1 KB (checked in by kmalkki, 11 years ago)

(Kyösti) More cleanups

Redo i2c-core locks.

No longer pass controlling_mod in i2cproc_register_entry, use
client->driver->owner instead.

Comment out or remove obsolete parts of mkpatch for 2.5.
Currently it does not touch kernel build/configure system at all.

Cleanup #include order. Note that kernel headers are not to be
included for userland utilities, to promote binary compatibility of
utilities across kernel versions.

Remove bus_scans. Remove empty and unused algo_control and
debugging code that would not compile if uncommented.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
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/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and even
22   Frodo Looijaard <frodol@dds.nl> */
23
24/* $Id$ */
25
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/delay.h>
29#include <linux/slab.h>
30#include <linux/init.h>
31#include <linux/errno.h>
32#include <linux/sched.h>
33#include "i2c.h"
34#include "i2c-algo-bit.h"
35
36
37/* ----- global defines ----------------------------------------------- */
38#define DEB(x) if (i2c_debug>=1) x;
39#define DEB2(x) if (i2c_debug>=2) x;
40#define DEBSTAT(x) if (i2c_debug>=3) x; /* print several statistical values*/
41#define DEBPROTO(x) if (i2c_debug>=9) { x; }
42        /* debug the protocol by showing transferred bits */
43
44
45/* ----- global variables --------------------------------------------- */
46
47/* module parameters:
48 */
49static int i2c_debug;
50static int bit_test;    /* see if the line-setting functions work       */
51
52/* --- setting states on the bus with the right timing: --------------- */
53
54#define setsda(adap,val) adap->setsda(adap->data, val)
55#define setscl(adap,val) adap->setscl(adap->data, val)
56#define getsda(adap) adap->getsda(adap->data)
57#define getscl(adap) adap->getscl(adap->data)
58
59static inline void sdalo(struct i2c_algo_bit_data *adap)
60{
61        setsda(adap,0);
62        udelay(adap->udelay);
63}
64
65static inline void sdahi(struct i2c_algo_bit_data *adap)
66{
67        setsda(adap,1);
68        udelay(adap->udelay);
69}
70
71static inline void scllo(struct i2c_algo_bit_data *adap)
72{
73        setscl(adap,0);
74        udelay(adap->udelay);
75}
76
77/*
78 * Raise scl line, and do checking for delays. This is necessary for slower
79 * devices.
80 */
81static inline int sclhi(struct i2c_algo_bit_data *adap)
82{
83        int start;
84
85        setscl(adap,1);
86
87        /* Not all adapters have scl sense line... */
88        if (adap->getscl == NULL )
89                return 0;
90
91        start=jiffies;
92        while (! getscl(adap) ) {       
93                /* the hw knows how to read the clock line,
94                 * so we wait until it actually gets high.
95                 * This is safer as some chips may hold it low
96                 * while they are processing data internally.
97                 */
98                if (time_after_eq(jiffies, start+adap->timeout)) {
99                        return -ETIMEDOUT;
100                }
101                cond_resched();
102        }
103        DEBSTAT(printk(KERN_DEBUG "needed %ld jiffies\n", jiffies-start));
104        udelay(adap->udelay);
105        return 0;
106} 
107
108
109/* --- other auxiliary functions -------------------------------------- */
110static void i2c_start(struct i2c_algo_bit_data *adap) 
111{
112        /* assert: scl, sda are high */
113        DEBPROTO(printk("S "));
114        sdalo(adap);
115        scllo(adap);
116}
117
118static void i2c_repstart(struct i2c_algo_bit_data *adap) 
119{
120        /* scl, sda may not be high */
121        DEBPROTO(printk(" Sr "));
122        setsda(adap,1);
123        sclhi(adap);
124        udelay(adap->udelay);
125       
126        sdalo(adap);
127        scllo(adap);
128}
129
130
131static void i2c_stop(struct i2c_algo_bit_data *adap) 
132{
133        DEBPROTO(printk("P\n"));
134        /* assert: scl is low */
135        sdalo(adap);
136        sclhi(adap); 
137        sdahi(adap);
138}
139
140
141
142/* send a byte without start cond., look for arbitration,
143   check ackn. from slave */
144/* returns:
145 * 1 if the device acknowledged
146 * 0 if the device did not ack
147 * -ETIMEDOUT if an error occurred (while raising the scl line)
148 */
149static int i2c_outb(struct i2c_adapter *i2c_adap, char c)
150{
151        int i;
152        int sb;
153        int ack;
154        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
155
156        /* assert: scl is low */
157        for ( i=7 ; i>=0 ; i-- ) {
158                sb = c & ( 1 << i );
159                setsda(adap,sb);
160                udelay(adap->udelay);
161                DEBPROTO(printk(KERN_DEBUG "%d",sb!=0));
162                if (sclhi(adap)<0) { /* timed out */
163                        sdahi(adap); /* we don't want to block the net */
164                        DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at bit #%d\n", c&0xff, i));
165                        return -ETIMEDOUT;
166                };
167                /* do arbitration here:
168                 * if ( sb && ! getsda(adap) ) -> ouch! Get out of here.
169                 */
170                setscl(adap, 0 );
171                udelay(adap->udelay);
172        }
173        sdahi(adap);
174        if (sclhi(adap)<0){ /* timeout */
175            DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x, timeout at ack\n", c&0xff));
176            return -ETIMEDOUT;
177        };
178        /* read ack: SDA should be pulled down by slave */
179        ack=getsda(adap);       /* ack: sda is pulled low ->success.     */
180        DEB2(printk(KERN_DEBUG " i2c_outb: 0x%02x , getsda() = %d\n", c & 0xff, ack));
181
182        DEBPROTO( printk(KERN_DEBUG "[%2.2x]",c&0xff) );
183        DEBPROTO(if (0==ack){ printk(KERN_DEBUG " A ");} else printk(KERN_DEBUG " NA ") );
184        scllo(adap);
185        return 0==ack;          /* return 1 if device acked      */
186        /* assert: scl is low (sda undef) */
187}
188
189
190static int i2c_inb(struct i2c_adapter *i2c_adap) 
191{
192        /* read byte via i2c port, without start/stop sequence  */
193        /* acknowledge is sent in i2c_read.                     */
194        int i;
195        unsigned char indata=0;
196        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
197
198        /* assert: scl is low */
199        sdahi(adap);
200        for (i=0;i<8;i++) {
201                if (sclhi(adap)<0) { /* timeout */
202                        DEB2(printk(KERN_DEBUG " i2c_inb: timeout at bit #%d\n", 7-i));
203                        return -ETIMEDOUT;
204                };
205                indata *= 2;
206                if ( getsda(adap) ) 
207                        indata |= 0x01;
208                scllo(adap);
209        }
210        /* assert: scl is low */
211        DEB2(printk(KERN_DEBUG "i2c_inb: 0x%02x\n", indata & 0xff));
212
213        DEBPROTO(printk(KERN_DEBUG " 0x%02x", indata & 0xff));
214        return (int) (indata & 0xff);
215}
216
217/*
218 * Sanity check for the adapter hardware - check the reaction of
219 * the bus lines only if it seems to be idle.
220 */
221static int test_bus(struct i2c_algo_bit_data *adap, char* name) {
222        int scl,sda;
223        sda=getsda(adap);
224        if (adap->getscl==NULL) {
225                printk(KERN_WARNING "i2c-algo-bit.o: Warning: Adapter can't read from clock line - skipping test.\n");
226                return 0;               
227        }
228        scl=getscl(adap);
229        printk(KERN_INFO "i2c-algo-bit.o: Adapter: %s scl: %d  sda: %d -- testing...\n",
230               name,getscl(adap),getsda(adap));
231        if (!scl || !sda ) {
232                printk(KERN_INFO " i2c-algo-bit.o: %s seems to be busy.\n",name);
233                goto bailout;
234        }
235        sdalo(adap);
236        printk(KERN_DEBUG "i2c-algo-bit.o:1 scl: %d  sda: %d \n",getscl(adap),
237               getsda(adap));
238        if ( 0 != getsda(adap) ) {
239                printk(KERN_WARNING "i2c-algo-bit.o: %s SDA stuck high!\n",name);
240                sdahi(adap);
241                goto bailout;
242        }
243        if ( 0 == getscl(adap) ) {
244                printk(KERN_WARNING "i2c-algo-bit.o: %s SCL unexpected low while pulling SDA low!\n",
245                        name);
246                goto bailout;
247        }               
248        sdahi(adap);
249        printk(KERN_DEBUG "i2c-algo-bit.o:2 scl: %d  sda: %d \n",getscl(adap),
250               getsda(adap));
251        if ( 0 == getsda(adap) ) {
252                printk(KERN_WARNING "i2c-algo-bit.o: %s SDA stuck low!\n",name);
253                sdahi(adap);
254                goto bailout;
255        }
256        if ( 0 == getscl(adap) ) {
257                printk(KERN_WARNING "i2c-algo-bit.o: %s SCL unexpected low while SDA high!\n",
258                       name);
259        goto bailout;
260        }
261        scllo(adap);
262        printk(KERN_DEBUG "i2c-algo-bit.o:3 scl: %d  sda: %d \n",getscl(adap),
263               getsda(adap));
264        if ( 0 != getscl(adap) ) {
265                printk(KERN_WARNING "i2c-algo-bit.o: %s SCL stuck high!\n",name);
266                sclhi(adap);
267                goto bailout;
268        }
269        if ( 0 == getsda(adap) ) {
270                printk(KERN_WARNING "i2c-algo-bit.o: %s SDA unexpected low while pulling SCL low!\n",
271                        name);
272                goto bailout;
273        }
274        sclhi(adap);
275        printk(KERN_DEBUG "i2c-algo-bit.o:4 scl: %d  sda: %d \n",getscl(adap),
276               getsda(adap));
277        if ( 0 == getscl(adap) ) {
278                printk(KERN_WARNING "i2c-algo-bit.o: %s SCL stuck low!\n",name);
279                sclhi(adap);
280                goto bailout;
281        }
282        if ( 0 == getsda(adap) ) {
283                printk(KERN_WARNING "i2c-algo-bit.o: %s SDA unexpected low while SCL high!\n",
284                        name);
285                goto bailout;
286        }
287        printk(KERN_INFO "i2c-algo-bit.o: %s passed test.\n",name);
288        return 0;
289bailout:
290        sdahi(adap);
291        sclhi(adap);
292        return -ENODEV;
293}
294
295/* ----- Utility functions
296 */
297
298/* try_address tries to contact a chip for a number of
299 * times before it gives up.
300 * return values:
301 * 1 chip answered
302 * 0 chip did not answer
303 * -x transmission error
304 */
305static inline int try_address(struct i2c_adapter *i2c_adap,
306                       unsigned char addr, int retries)
307{
308        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
309        int i,ret = -1;
310        for (i=0;i<=retries;i++) {
311                ret = i2c_outb(i2c_adap,addr);
312                if (ret==1)
313                        break;  /* success! */
314                i2c_stop(adap);
315                udelay(5/*adap->udelay*/);
316                if (i==retries)  /* no success */
317                        break;
318                i2c_start(adap);
319                udelay(adap->udelay);
320        }
321        DEB2(if (i)
322             printk(KERN_DEBUG "i2c-algo-bit.o: Used %d tries to %s client at 0x%02x : %s\n",
323                    i+1, addr & 1 ? "read" : "write", addr>>1,
324                    ret==1 ? "success" : ret==0 ? "no ack" : "failed, timeout?" )
325            );
326        return ret;
327}
328
329static int sendbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
330{
331        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
332        char c;
333        const char *temp = msg->buf;
334        int count = msg->len;
335        unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK; 
336        int retval;
337        int wrcount=0;
338
339        while (count > 0) {
340                c = *temp;
341                DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: %s sendbytes: writing %2.2X\n",
342                            i2c_adap->name, c&0xff));
343                retval = i2c_outb(i2c_adap,c);
344                if ((retval>0) || (nak_ok && (retval==0)))  { /* ok or ignored NAK */
345                        count--; 
346                        temp++;
347                        wrcount++;
348                } else { /* arbitration or no acknowledge */
349                        printk(KERN_ERR "i2c-algo-bit.o: %s sendbytes: error - bailout.\n",
350                               i2c_adap->name);
351                        i2c_stop(adap);
352                        return (retval<0)? retval : -EFAULT;
353                                /* got a better one ?? */
354                }
355#if 0
356                /* from asm/delay.h */
357                __delay(adap->mdelay * (loops_per_sec / 1000) );
358#endif
359        }
360        return wrcount;
361}
362
363static inline int readbytes(struct i2c_adapter *i2c_adap, struct i2c_msg *msg)
364{
365        int inval;
366        int rdcount=0;          /* counts bytes read */
367        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
368        char *temp = msg->buf;
369        int count = msg->len;
370
371        while (count > 0) {
372                inval = i2c_inb(i2c_adap);
373/*printk("%#02x ",inval); if ( ! (count % 16) ) printk("\n"); */
374                if (inval>=0) {
375                        *temp = inval;
376                        rdcount++;
377                } else {   /* read timed out */
378                        printk(KERN_ERR "i2c-algo-bit.o: readbytes: i2c_inb timed out.\n");
379                        break;
380                }
381
382                if ( count > 1 ) {              /* send ack */
383                        sdalo(adap);
384                        DEBPROTO(printk(" Am "));
385                } else {
386                        sdahi(adap);    /* neg. ack on last byte */
387                        DEBPROTO(printk(" NAm "));
388                }
389                if (sclhi(adap)<0) {    /* timeout */
390                        sdahi(adap);
391                        printk(KERN_ERR "i2c-algo-bit.o: readbytes: Timeout at ack\n");
392                        return -ETIMEDOUT;
393                };
394                scllo(adap);
395                sdahi(adap);
396                temp++;
397                count--;
398        }
399        return rdcount;
400}
401
402/* doAddress initiates the transfer by generating the start condition (in
403 * try_address) and transmits the address in the necessary format to handle
404 * reads, writes as well as 10bit-addresses.
405 * returns:
406 *  0 everything went okay, the chip ack'ed, or IGNORE_NAK flag was set
407 * -x an error occurred (like: -EREMOTEIO if the device did not answer, or
408 *      -ETIMEDOUT, for example if the lines are stuck...)
409 */
410static inline int bit_doAddress(struct i2c_adapter *i2c_adap, struct i2c_msg *msg) 
411{
412        unsigned short flags = msg->flags;
413        unsigned short nak_ok = msg->flags & I2C_M_IGNORE_NAK;
414        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
415
416        unsigned char addr;
417        int ret, retries;
418
419        retries = nak_ok ? 0 : i2c_adap->retries;
420       
421        if ( (flags & I2C_M_TEN)  ) { 
422                /* a ten bit address */
423                addr = 0xf0 | (( msg->addr >> 7) & 0x03);
424                DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
425                /* try extended address code...*/
426                ret = try_address(i2c_adap, addr, retries);
427                if ((ret != 1) && !nak_ok)  {
428                        printk(KERN_ERR "died at extended address code.\n");
429                        return -EREMOTEIO;
430                }
431                /* the remaining 8 bit address */
432                ret = i2c_outb(i2c_adap,msg->addr & 0x7f);
433                if ((ret != 1) && !nak_ok) {
434                        /* the chip did not ack / xmission error occurred */
435                        printk(KERN_ERR "died at 2nd address code.\n");
436                        return -EREMOTEIO;
437                }
438                if ( flags & I2C_M_RD ) {
439                        i2c_repstart(adap);
440                        /* okay, now switch into reading mode */
441                        addr |= 0x01;
442                        ret = try_address(i2c_adap, addr, retries);
443                        if ((ret!=1) && !nak_ok) {
444                                printk(KERN_ERR "died at extended address code.\n");
445                                return -EREMOTEIO;
446                        }
447                }
448        } else {                /* normal 7bit address  */
449                addr = ( msg->addr << 1 );
450                if (flags & I2C_M_RD )
451                        addr |= 1;
452                if (flags & I2C_M_REV_DIR_ADDR )
453                        addr ^= 1;
454                ret = try_address(i2c_adap, addr, retries);
455                if ((ret!=1) && !nak_ok)
456                        return -EREMOTEIO;
457        }
458
459        return 0;
460}
461
462static int bit_xfer(struct i2c_adapter *i2c_adap,
463                    struct i2c_msg msgs[], int num)
464{
465        struct i2c_msg *pmsg;
466        struct i2c_algo_bit_data *adap = i2c_adap->algo_data;
467       
468        int i,ret;
469        unsigned short nak_ok;
470
471        i2c_start(adap);
472        for (i=0;i<num;i++) {
473                pmsg = &msgs[i];
474                nak_ok = pmsg->flags & I2C_M_IGNORE_NAK; 
475                if (!(pmsg->flags & I2C_M_NOSTART)) {
476                        if (i) {
477                                i2c_repstart(adap);
478                        }
479                        ret = bit_doAddress(i2c_adap, pmsg);
480                        if ((ret != 0) && !nak_ok) {
481                            DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: NAK from device addr %2.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);
489                        DEB2(printk(KERN_DEBUG "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);
496                        DEB2(printk(KERN_DEBUG "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
506static u32 bit_func(struct i2c_adapter *adap)
507{
508        return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
509               I2C_FUNC_PROTOCOL_MANGLING;
510}
511
512
513/* -----exported algorithm data: -------------------------------------  */
514
515static struct i2c_algorithm i2c_bit_algo = {
516        .owner          = THIS_MODULE,
517        .name           = "Bit-shift algorithm",
518        .id             = I2C_ALGO_BIT,
519        .master_xfer    = bit_xfer,
520        .functionality  = bit_func,
521};
522
523/*
524 * registering functions to load algorithms at runtime
525 */
526int i2c_bit_add_bus(struct i2c_adapter *adap)
527{
528        int i;
529        struct i2c_algo_bit_data *bit_adap = adap->algo_data;
530
531        if (bit_test) {
532                int ret = test_bus(bit_adap, adap->name);
533                if (ret<0)
534                        return -ENODEV;
535        }
536
537        DEB2(printk(KERN_DEBUG "i2c-algo-bit.o: hw routines for %s registered.\n",
538                    adap->name));
539
540        /* register new adapter to i2c module... */
541
542        adap->id |= i2c_bit_algo.id;
543        adap->algo = &i2c_bit_algo;
544
545        adap->timeout = 100;    /* default values, should       */
546        adap->retries = 3;      /* be replaced by defines       */
547
548        i2c_add_adapter(adap);
549        return 0;
550}
551
552
553int i2c_bit_del_bus(struct i2c_adapter *adap)
554{
555        return i2c_del_adapter(adap);
556}
557
558EXPORT_SYMBOL(i2c_bit_add_bus);
559EXPORT_SYMBOL(i2c_bit_del_bus);
560
561MODULE_AUTHOR("Simon G. Vogl <simon@tk.uni-linz.ac.at>");
562MODULE_DESCRIPTION("I2C-Bus bit-banging algorithm");
563MODULE_LICENSE("GPL");
564
565MODULE_PARM(bit_test, "i");
566MODULE_PARM(i2c_debug,"i");
567
568MODULE_PARM_DESC(bit_test, "Test the lines of the bus to see if it is stuck");
569MODULE_PARM_DESC(i2c_debug,
570                 "debug level - 0 off; 1 normal; 2,3 more verbose; 9 bit-protocol");
Note: See TracBrowser for help on using the browser.