Subversion Repositories Kolibri OS

Rev

Rev 1963 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1125 serge 1
/* i2c-core.c - a device driver for the iic-bus interface		     */
2
/* ------------------------------------------------------------------------- */
3
/*   Copyright (C) 1995-99 Simon G. Vogl
4
 
5
    This program is free software; you can redistribute it and/or modify
6
    it under the terms of the GNU General Public License as published by
7
    the Free Software Foundation; either version 2 of the License, or
8
    (at your option) any later version.
9
 
10
    This program is distributed in the hope that it will be useful,
11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
    GNU General Public License for more details.
14
 
15
    You should have received a copy of the GNU General Public License
16
    along with this program; if not, write to the Free Software
17
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.		     */
18
/* ------------------------------------------------------------------------- */
19
 
20
/* With some changes from Kyösti Mälkki .
21
   All SMBus-related things are written by Frodo Looijaard 
22
   SMBus 2.0 support by Mark Studebaker  and
23
   Jean Delvare  */
24
 
25
#include 
26
#include 
27
#include 
28
#include 
29
#include 
30
 
31
 
32
/**
33
 * i2c_transfer - execute a single or combined I2C message
34
 * @adap: Handle to I2C bus
35
 * @msgs: One or more messages to execute before STOP is issued to
36
 *  terminate the operation; each message begins with a START.
37
 * @num: Number of messages to be executed.
38
 *
39
 * Returns negative errno, else the number of messages executed.
40
 *
41
 * Note that there is no requirement that each message be sent to
42
 * the same slave address, although that is the most common model.
43
 */
44
int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
45
{
46
    unsigned long orig_jiffies;
47
    int ret, try;
48
 
49
    /* REVISIT the fault reporting model here is weak:
50
     *
51
     *  - When we get an error after receiving N bytes from a slave,
52
     *    there is no way to report "N".
53
     *
54
     *  - When we get a NAK after transmitting N bytes to a slave,
55
     *    there is no way to report "N" ... or to let the master
56
     *    continue executing the rest of this combined message, if
57
     *    that's the appropriate response.
58
     *
59
     *  - When for example "num" is two and we successfully complete
60
     *    the first message but get an error part way through the
61
     *    second, it's unclear whether that should be reported as
62
     *    one (discarding status on the second message) or errno
63
     *    (discarding status on the first one).
64
     */
65
 
66
    if (adap->algo->master_xfer) {
67
#ifdef DEBUG
68
        for (ret = 0; ret < num; ret++) {
69
            dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "
70
                "len=%d%s\n", ret, (msgs[ret].flags & I2C_M_RD)
71
                ? 'R' : 'W', msgs[ret].addr, msgs[ret].len,
72
                (msgs[ret].flags & I2C_M_RECV_LEN) ? "+" : "");
73
        }
74
#endif
75
 
76
//        if (in_atomic() || irqs_disabled()) {
77
//            ret = mutex_trylock(&adap->bus_lock);
78
//            if (!ret)
79
//                /* I2C activity is ongoing. */
80
//                return -EAGAIN;
81
//        } else {
82
//            mutex_lock_nested(&adap->bus_lock, adap->level);
83
//        }
84
 
85
        /* Retry automatically on arbitration loss */
86
//        orig_jiffies = jiffies;
87
        for (ret = 0, try = 0; try <= adap->retries; try++) {
88
            ret = adap->algo->master_xfer(adap, msgs, num);
89
            if (ret != -EAGAIN)
90
                break;
91
//            if (time_after(jiffies, orig_jiffies + adap->timeout))
92
//                break;
93
                delay(1);
94
        }
95
//        mutex_unlock(&adap->bus_lock);
96
 
97
        return ret;
98
    } else {
99
//        dev_dbg(&adap->dev, "I2C level transfers not supported\n");
100
        return -EOPNOTSUPP;
101
    }
102
}
103
EXPORT_SYMBOL(i2c_transfer);
104