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

Revision 3765, 12.9 KB (checked in by kmalkki, 12 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-pcf.c i2c driver algorithms for PCF8584 adapters                 */
3/* ------------------------------------------------------------------------- */
4/*   Copyright (C) 1995-1997 Simon G. Vogl
5                   1998-2000 Hans Berglund
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/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
23   Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey
24   <mbailey@littlefeet-inc.com> */
25
26/* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
27   messages, proper stop/repstart signaling during receive,
28   added detect code */
29
30#include <linux/kernel.h>
31#include <linux/module.h>
32#include <linux/delay.h>
33#include <linux/slab.h>
34#include <linux/init.h>
35#include <linux/errno.h>
36#include "i2c.h"
37#include "i2c-algo-pcf.h"
38
39
40/* ----- global defines ----------------------------------------------- */
41#define DEB(x) if (i2c_debug>=1) x
42#define DEB2(x) if (i2c_debug>=2) x
43#define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/
44#define DEBPROTO(x) if (i2c_debug>=9) x;
45        /* debug the protocol by showing transferred bits */
46#define DEF_TIMEOUT 16
47
48/* module parameters:
49 */
50static int i2c_debug=0;
51
52/* --- setting states on the bus with the right timing: --------------- */
53
54#define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
55#define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
56#define get_own(adap) adap->getown(adap->data)
57#define get_clock(adap) adap->getclock(adap->data)
58#define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
59#define i2c_inb(adap) adap->getpcf(adap->data, 0)
60
61/* --- other auxiliary functions -------------------------------------- */
62
63static void i2c_start(struct i2c_algo_pcf_data *adap) 
64{
65        DEBPROTO(printk("S "));
66        set_pcf(adap, 1, I2C_PCF_START);
67}
68
69static void i2c_repstart(struct i2c_algo_pcf_data *adap) 
70{
71        DEBPROTO(printk(" Sr "));
72        set_pcf(adap, 1, I2C_PCF_REPSTART);
73}
74
75
76static void i2c_stop(struct i2c_algo_pcf_data *adap) 
77{
78        DEBPROTO(printk("P\n"));
79        set_pcf(adap, 1, I2C_PCF_STOP);
80}
81
82
83static int wait_for_bb(struct i2c_algo_pcf_data *adap) {
84
85        int timeout = DEF_TIMEOUT;
86        int status;
87
88        status = get_pcf(adap, 1);
89#ifndef STUB_I2C
90        while (timeout-- && !(status & I2C_PCF_BB)) {
91                udelay(100); /* wait for 100 us */
92                status = get_pcf(adap, 1);
93        }
94#endif
95        if (timeout <= 0) {
96                printk(KERN_ERR "Timeout waiting for Bus Busy\n");
97        }
98       
99        return (timeout<=0);
100}
101
102
103static inline void pcf_sleep(unsigned long timeout)
104{
105        schedule_timeout( timeout * HZ);
106}
107
108
109static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) {
110
111        int timeout = DEF_TIMEOUT;
112
113        *status = get_pcf(adap, 1);
114#ifndef STUB_I2C
115        while (timeout-- && (*status & I2C_PCF_PIN)) {
116                adap->waitforpin();
117                *status = get_pcf(adap, 1);
118        }
119#endif
120        if (timeout <= 0)
121                return(-1);
122        else
123                return(0);
124}
125
126/*
127 * This should perform the 'PCF8584 initialization sequence' as described
128 * in the Philips IC12 data book (1995, Aug 29).
129 * There should be a 30 clock cycle wait after reset, I assume this
130 * has been fulfilled.
131 * There should be a delay at the end equal to the longest I2C message
132 * to synchronize the BB-bit (in multimaster systems). How long is
133 * this? I assume 1 second is always long enough.
134 *
135 * vdovikin: added detect code for PCF8584
136 */
137static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
138{
139        unsigned char temp;
140
141        DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1)));
142
143        /* S1=0x80: S0 selected, serial interface off */
144        set_pcf(adap, 1, I2C_PCF_PIN);
145        /* check to see S1 now used as R/W ctrl -
146           PCF8584 does that when ESO is zero */
147        if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
148                DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
149                return -ENXIO; /* definetly not PCF8584 */
150        }
151
152        /* load own address in S0, effective address is (own << 1)      */
153        i2c_outb(adap, get_own(adap));
154        /* check it's realy writen */
155        if ((temp = i2c_inb(adap)) != get_own(adap)) {
156                DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
157                return -ENXIO;
158        }
159
160        /* S1=0xA0, next byte in S2                                     */
161        set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
162        /* check to see S2 now selected */
163        if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
164                DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
165                return -ENXIO;
166        }
167
168        /* load clock register S2                                       */
169        i2c_outb(adap, get_clock(adap));
170        /* check it's realy writen, the only 5 lowest bits does matter */
171        if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
172                DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
173                return -ENXIO;
174        }
175
176        /* Enable serial interface, idle, S0 selected                   */
177        set_pcf(adap, 1, I2C_PCF_IDLE);
178
179        /* check to see PCF is realy idled and we can access status register */
180        if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
181                DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
182                return -ENXIO;
183        }
184       
185        printk(KERN_DEBUG "i2c-algo-pcf.o: deteted and initialized PCF8584.\n");
186
187        return 0;
188}
189
190
191/* ----- Utility functions
192 */
193
194static inline int try_address(struct i2c_algo_pcf_data *adap,
195                       unsigned char addr, int retries)
196{
197        int i, status, ret = -1;
198        for (i=0;i<retries;i++) {
199                i2c_outb(adap, addr);
200                i2c_start(adap);
201                status = get_pcf(adap, 1);
202                if (wait_for_pin(adap, &status) >= 0) {
203                        if ((status & I2C_PCF_LRB) == 0) { 
204                                i2c_stop(adap);
205                                break;  /* success! */
206                        }
207                }
208                i2c_stop(adap);
209                udelay(adap->udelay);
210        }
211        DEB2(if (i) printk(KERN_DEBUG "i2c-algo-pcf.o: needed %d retries for %d\n",i,
212                           addr));
213        return ret;
214}
215
216
217static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
218                         int count, int last)
219{
220        struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
221        int wrcount, status, timeout;
222   
223        for (wrcount=0; wrcount<count; ++wrcount) {
224                DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: %s i2c_write: writing %2.2X\n",
225                      i2c_adap->name, buf[wrcount]&0xff));
226                i2c_outb(adap, buf[wrcount]);
227                timeout = wait_for_pin(adap, &status);
228                if (timeout) {
229                        i2c_stop(adap);
230                        printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: "
231                               "error - timeout.\n", i2c_adap->name);
232                        return -EREMOTEIO; /* got a better one ?? */
233                }
234#ifndef STUB_I2C
235                if (status & I2C_PCF_LRB) {
236                        i2c_stop(adap);
237                        printk(KERN_ERR "i2c-algo-pcf.o: %s i2c_write: "
238                               "error - no ack.\n", i2c_adap->name);
239                        return -EREMOTEIO; /* got a better one ?? */
240                }
241#endif
242        }
243        if (last) {
244                i2c_stop(adap);
245        }
246        else {
247                i2c_repstart(adap);
248        }
249
250        return (wrcount);
251}
252
253
254static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
255                         int count, int last)
256{
257        int i, status;
258        struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
259
260        /* increment number of bytes to read by one -- read dummy byte */
261        for (i = 0; i <= count; i++) {
262
263                if (wait_for_pin(adap, &status)) {
264                        i2c_stop(adap);
265                        printk(KERN_ERR "i2c-algo-pcf.o: pcf_readbytes timed out.\n");
266                        return (-1);
267                }
268
269#ifndef STUB_I2C
270                if ((status & I2C_PCF_LRB) && (i != count)) {
271                        i2c_stop(adap);
272                        printk(KERN_ERR "i2c-algo-pcf.o: i2c_read: i2c_inb, No ack.\n");
273                        return (-1);
274                }
275#endif
276               
277                if (i == count - 1) {
278                        set_pcf(adap, 1, I2C_PCF_ESO);
279                } else 
280                if (i == count) {
281                        if (last) {
282                                i2c_stop(adap);
283                        } else {
284                                i2c_repstart(adap);
285                        }
286                };
287
288                if (i) {
289                        buf[i - 1] = i2c_inb(adap);
290                } else {
291                        i2c_inb(adap); /* dummy read */
292                }
293        }
294
295        return (i - 1);
296}
297
298
299static inline int pcf_doAddress(struct i2c_algo_pcf_data *adap,
300                                struct i2c_msg *msg, int retries) 
301{
302        unsigned short flags = msg->flags;
303        unsigned char addr;
304        int ret;
305        if ( (flags & I2C_M_TEN)  ) { 
306                /* a ten bit address */
307                addr = 0xf0 | (( msg->addr >> 7) & 0x03);
308                DEB2(printk(KERN_DEBUG "addr0: %d\n",addr));
309                /* try extended address code...*/
310                ret = try_address(adap, addr, retries);
311                if (ret!=1) {
312                        printk(KERN_ERR "died at extended address code.\n");
313                        return -EREMOTEIO;
314                }
315                /* the remaining 8 bit address */
316                i2c_outb(adap,msg->addr & 0x7f);
317/* Status check comes here */
318                if (ret != 1) {
319                        printk(KERN_ERR "died at 2nd address code.\n");
320                        return -EREMOTEIO;
321                }
322                if ( flags & I2C_M_RD ) {
323                        i2c_repstart(adap);
324                        /* okay, now switch into reading mode */
325                        addr |= 0x01;
326                        ret = try_address(adap, addr, retries);
327                        if (ret!=1) {
328                                printk(KERN_ERR "died at extended address code.\n");
329                                return -EREMOTEIO;
330                        }
331                }
332        } else {                /* normal 7bit address  */
333                addr = ( msg->addr << 1 );
334                if (flags & I2C_M_RD )
335                        addr |= 1;
336                if (flags & I2C_M_REV_DIR_ADDR )
337                        addr ^= 1;
338                i2c_outb(adap, addr);
339        }
340        return 0;
341}
342
343static int pcf_xfer(struct i2c_adapter *i2c_adap,
344                    struct i2c_msg msgs[], 
345                    int num)
346{
347        struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
348        struct i2c_msg *pmsg;
349        int i;
350        int ret=0, timeout, status;
351   
352
353        /* Check for bus busy */
354        timeout = wait_for_bb(adap);
355        if (timeout) {
356                DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
357                            "Timeout waiting for BB in pcf_xfer\n");)
358                return -EIO;
359        }
360       
361        for (i = 0;ret >= 0 && i < num; i++) {
362                pmsg = &msgs[i];
363
364                DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
365                     pmsg->flags & I2C_M_RD ? "read" : "write",
366                     pmsg->len, pmsg->addr, i + 1, num);)
367   
368                ret = pcf_doAddress(adap, pmsg, i2c_adap->retries);
369
370                /* Send START */
371                if (i == 0) {
372                        i2c_start(adap); 
373                }
374   
375                /* Wait for PIN (pending interrupt NOT) */
376                timeout = wait_for_pin(adap, &status);
377                if (timeout) {
378                        i2c_stop(adap);
379                        DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
380                                    "for PIN(1) in pcf_xfer\n");)
381                        return (-EREMOTEIO);
382                }
383   
384#ifndef STUB_I2C
385                /* Check LRB (last rcvd bit - slave ack) */
386                if (status & I2C_PCF_LRB) {
387                        i2c_stop(adap);
388                        DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
389                        return (-EREMOTEIO);
390                }
391#endif
392   
393                DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
394                            i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
395   
396                /* Read */
397                if (pmsg->flags & I2C_M_RD) {
398                        /* read bytes into buffer*/
399                        ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
400                                            (i + 1 == num));
401       
402                        if (ret != pmsg->len) {
403                                DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
404                                            "only read %d bytes.\n",ret));
405                        } else {
406                                DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
407                        }
408                } else { /* Write */
409                        ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
410                                            (i + 1 == num));
411       
412                        if (ret != pmsg->len) {
413                                DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
414                                            "only wrote %d bytes.\n",ret));
415                        } else {
416                                DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret));
417                        }
418                }
419        }
420
421        return (i);
422}
423
424static u32 pcf_func(struct i2c_adapter *adap)
425{
426        return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | 
427               I2C_FUNC_PROTOCOL_MANGLING; 
428}
429
430/* -----exported algorithm data: -------------------------------------  */
431
432static struct i2c_algorithm pcf_algo = {
433        .owner          = THIS_MODULE,
434        .name           = "PCF8584 algorithm",
435        .id             = I2C_ALGO_PCF,
436        .master_xfer    = pcf_xfer,
437        .functionality  = pcf_func,
438};
439
440/*
441 * registering functions to load algorithms at runtime
442 */
443int i2c_pcf_add_bus(struct i2c_adapter *adap)
444{
445        int i, status;
446        struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
447
448        DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: hw routines for %s registered.\n",
449                    adap->name));
450
451        /* register new adapter to i2c module... */
452
453        adap->id |= pcf_algo.id;
454        adap->algo = &pcf_algo;
455
456        adap->timeout = 100;            /* default values, should       */
457        adap->retries = 3;              /* be replaced by defines       */
458
459        if ((i = pcf_init_8584(pcf_adap))) {
460                return i;
461        }
462
463        i2c_add_adapter(adap);
464        return 0;
465}
466
467
468int i2c_pcf_del_bus(struct i2c_adapter *adap)
469{
470        return i2c_del_adapter(adap);
471}
472
473EXPORT_SYMBOL(i2c_pcf_add_bus);
474EXPORT_SYMBOL(i2c_pcf_del_bus);
475
476MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
477MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
478MODULE_LICENSE("GPL");
479
480MODULE_PARM(i2c_debug,"i");
481MODULE_PARM_DESC(i2c_debug,
482        "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
Note: See TracBrowser for help on using the browser.