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 |
||
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 |