diff options
| -rw-r--r-- | drivers/i2c/algos/i2c-algo-pcf.c | 250 |
1 files changed, 115 insertions, 135 deletions
diff --git a/drivers/i2c/algos/i2c-algo-pcf.c b/drivers/i2c/algos/i2c-algo-pcf.c index 3e01992230b8..5906986d013b 100644 --- a/drivers/i2c/algos/i2c-algo-pcf.c +++ b/drivers/i2c/algos/i2c-algo-pcf.c | |||
| @@ -1,31 +1,30 @@ | |||
| 1 | /* ------------------------------------------------------------------------- */ | 1 | /* |
| 2 | /* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters */ | 2 | * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters |
| 3 | /* ------------------------------------------------------------------------- */ | 3 | * |
| 4 | /* Copyright (C) 1995-1997 Simon G. Vogl | 4 | * Copyright (C) 1995-1997 Simon G. Vogl |
| 5 | 1998-2000 Hans Berglund | 5 | * 1998-2000 Hans Berglund |
| 6 | 6 | * | |
| 7 | This program is free software; you can redistribute it and/or modify | 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 | 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 | 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | (at your option) any later version. | 10 | * (at your option) any later version. |
| 11 | 11 | * | |
| 12 | This program is distributed in the hope that it will be useful, | 12 | * This program is distributed in the hope that it will be useful, |
| 13 | but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 15 | GNU General Public License for more details. | 15 | * GNU General Public License for more details. |
| 16 | 16 | * | |
| 17 | You should have received a copy of the GNU General Public License | 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 | 18 | * along with this program; if not, write to the Free Software |
| 19 | Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ | 19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
| 20 | /* ------------------------------------------------------------------------- */ | 20 | * |
| 21 | 21 | * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and | |
| 22 | /* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and | 22 | * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey |
| 23 | Frodo Looijaard <frodol@dds.nl> ,and also from Martin Bailey | 23 | * <mbailey@littlefeet-inc.com> |
| 24 | <mbailey@littlefeet-inc.com> */ | 24 | * |
| 25 | 25 | * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple | |
| 26 | /* Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple | 26 | * messages, proper stop/repstart signaling during receive, added detect code |
| 27 | messages, proper stop/repstart signaling during receive, | 27 | */ |
| 28 | added detect code */ | ||
| 29 | 28 | ||
| 30 | #include <linux/kernel.h> | 29 | #include <linux/kernel.h> |
| 31 | #include <linux/module.h> | 30 | #include <linux/module.h> |
| @@ -38,17 +37,18 @@ | |||
| 38 | #include "i2c-algo-pcf.h" | 37 | #include "i2c-algo-pcf.h" |
| 39 | 38 | ||
| 40 | 39 | ||
| 41 | #define DEB2(x) if (i2c_debug>=2) x | 40 | #define DEB2(x) if (i2c_debug >= 2) x |
| 42 | #define DEB3(x) if (i2c_debug>=3) x /* print several statistical values*/ | 41 | #define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */ |
| 43 | #define DEBPROTO(x) if (i2c_debug>=9) x; | 42 | #define DEBPROTO(x) if (i2c_debug >= 9) x; |
| 44 | /* debug the protocol by showing transferred bits */ | 43 | /* debug the protocol by showing transferred bits */ |
| 45 | #define DEF_TIMEOUT 16 | 44 | #define DEF_TIMEOUT 16 |
| 46 | 45 | ||
| 47 | /* module parameters: | 46 | /* |
| 47 | * module parameters: | ||
| 48 | */ | 48 | */ |
| 49 | static int i2c_debug; | 49 | static int i2c_debug; |
| 50 | 50 | ||
| 51 | /* --- setting states on the bus with the right timing: --------------- */ | 51 | /* setting states on the bus with the right timing: */ |
| 52 | 52 | ||
| 53 | #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val) | 53 | #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val) |
| 54 | #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl) | 54 | #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl) |
| @@ -57,22 +57,21 @@ static int i2c_debug; | |||
| 57 | #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val) | 57 | #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val) |
| 58 | #define i2c_inb(adap) adap->getpcf(adap->data, 0) | 58 | #define i2c_inb(adap) adap->getpcf(adap->data, 0) |
| 59 | 59 | ||
| 60 | /* --- other auxiliary functions -------------------------------------- */ | 60 | /* other auxiliary functions */ |
| 61 | 61 | ||
| 62 | static void i2c_start(struct i2c_algo_pcf_data *adap) | 62 | static void i2c_start(struct i2c_algo_pcf_data *adap) |
| 63 | { | 63 | { |
| 64 | DEBPROTO(printk("S ")); | 64 | DEBPROTO(printk("S ")); |
| 65 | set_pcf(adap, 1, I2C_PCF_START); | 65 | set_pcf(adap, 1, I2C_PCF_START); |
| 66 | } | 66 | } |
| 67 | 67 | ||
| 68 | static void i2c_repstart(struct i2c_algo_pcf_data *adap) | 68 | static void i2c_repstart(struct i2c_algo_pcf_data *adap) |
| 69 | { | 69 | { |
| 70 | DEBPROTO(printk(" Sr ")); | 70 | DEBPROTO(printk(" Sr ")); |
| 71 | set_pcf(adap, 1, I2C_PCF_REPSTART); | 71 | set_pcf(adap, 1, I2C_PCF_REPSTART); |
| 72 | } | 72 | } |
| 73 | 73 | ||
| 74 | 74 | static void i2c_stop(struct i2c_algo_pcf_data *adap) | |
| 75 | static void i2c_stop(struct i2c_algo_pcf_data *adap) | ||
| 76 | { | 75 | { |
| 77 | DEBPROTO(printk("P\n")); | 76 | DEBPROTO(printk("P\n")); |
| 78 | set_pcf(adap, 1, I2C_PCF_STOP); | 77 | set_pcf(adap, 1, I2C_PCF_STOP); |
| @@ -82,17 +81,17 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) | |||
| 82 | { | 81 | { |
| 83 | DEB2(printk(KERN_INFO | 82 | DEB2(printk(KERN_INFO |
| 84 | "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", | 83 | "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n", |
| 85 | *status)); | 84 | *status)); |
| 86 | 85 | /* | |
| 87 | /* Cleanup from LAB -- reset and enable ESO. | 86 | * Cleanup from LAB -- reset and enable ESO. |
| 88 | * This resets the PCF8584; since we've lost the bus, no | 87 | * This resets the PCF8584; since we've lost the bus, no |
| 89 | * further attempts should be made by callers to clean up | 88 | * further attempts should be made by callers to clean up |
| 90 | * (no i2c_stop() etc.) | 89 | * (no i2c_stop() etc.) |
| 91 | */ | 90 | */ |
| 92 | set_pcf(adap, 1, I2C_PCF_PIN); | 91 | set_pcf(adap, 1, I2C_PCF_PIN); |
| 93 | set_pcf(adap, 1, I2C_PCF_ESO); | 92 | set_pcf(adap, 1, I2C_PCF_ESO); |
| 94 | 93 | /* | |
| 95 | /* We pause for a time period sufficient for any running | 94 | * We pause for a time period sufficient for any running |
| 96 | * I2C transaction to complete -- the arbitration logic won't | 95 | * I2C transaction to complete -- the arbitration logic won't |
| 97 | * work properly until the next START is seen. | 96 | * work properly until the next START is seen. |
| 98 | * It is assumed the bus driver or client has set a proper value. | 97 | * It is assumed the bus driver or client has set a proper value. |
| @@ -108,48 +107,48 @@ static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status) | |||
| 108 | get_pcf(adap, 1))); | 107 | get_pcf(adap, 1))); |
| 109 | } | 108 | } |
| 110 | 109 | ||
| 111 | static int wait_for_bb(struct i2c_algo_pcf_data *adap) { | 110 | static int wait_for_bb(struct i2c_algo_pcf_data *adap) |
| 111 | { | ||
| 112 | 112 | ||
| 113 | int timeout = DEF_TIMEOUT; | 113 | int timeout = DEF_TIMEOUT; |
| 114 | int status; | 114 | int status; |
| 115 | 115 | ||
| 116 | status = get_pcf(adap, 1); | 116 | status = get_pcf(adap, 1); |
| 117 | #ifndef STUB_I2C | 117 | |
| 118 | while (timeout-- && !(status & I2C_PCF_BB)) { | 118 | while (timeout-- && !(status & I2C_PCF_BB)) { |
| 119 | udelay(100); /* wait for 100 us */ | 119 | udelay(100); /* wait for 100 us */ |
| 120 | status = get_pcf(adap, 1); | 120 | status = get_pcf(adap, 1); |
| 121 | } | 121 | } |
| 122 | #endif | 122 | |
| 123 | if (timeout <= 0) { | 123 | if (timeout <= 0) |
| 124 | printk(KERN_ERR "Timeout waiting for Bus Busy\n"); | 124 | printk(KERN_ERR "Timeout waiting for Bus Busy\n"); |
| 125 | } | ||
| 126 | |||
| 127 | return (timeout<=0); | ||
| 128 | } | ||
| 129 | 125 | ||
| 126 | return timeout <= 0; | ||
| 127 | } | ||
| 130 | 128 | ||
| 131 | static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) { | 129 | static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status) |
| 130 | { | ||
| 132 | 131 | ||
| 133 | int timeout = DEF_TIMEOUT; | 132 | int timeout = DEF_TIMEOUT; |
| 134 | 133 | ||
| 135 | *status = get_pcf(adap, 1); | 134 | *status = get_pcf(adap, 1); |
| 136 | #ifndef STUB_I2C | 135 | |
| 137 | while (timeout-- && (*status & I2C_PCF_PIN)) { | 136 | while (timeout-- && (*status & I2C_PCF_PIN)) { |
| 138 | adap->waitforpin(adap->data); | 137 | adap->waitforpin(adap->data); |
| 139 | *status = get_pcf(adap, 1); | 138 | *status = get_pcf(adap, 1); |
| 140 | } | 139 | } |
| 141 | if (*status & I2C_PCF_LAB) { | 140 | if (*status & I2C_PCF_LAB) { |
| 142 | handle_lab(adap, status); | 141 | handle_lab(adap, status); |
| 143 | return(-EINTR); | 142 | return -EINTR; |
| 144 | } | 143 | } |
| 145 | #endif | 144 | |
| 146 | if (timeout <= 0) | 145 | if (timeout <= 0) |
| 147 | return(-1); | 146 | return -1; |
| 148 | else | 147 | else |
| 149 | return(0); | 148 | return 0; |
| 150 | } | 149 | } |
| 151 | 150 | ||
| 152 | /* | 151 | /* |
| 153 | * This should perform the 'PCF8584 initialization sequence' as described | 152 | * This should perform the 'PCF8584 initialization sequence' as described |
| 154 | * in the Philips IC12 data book (1995, Aug 29). | 153 | * in the Philips IC12 data book (1995, Aug 29). |
| 155 | * There should be a 30 clock cycle wait after reset, I assume this | 154 | * There should be a 30 clock cycle wait after reset, I assume this |
| @@ -164,18 +163,21 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
| 164 | { | 163 | { |
| 165 | unsigned char temp; | 164 | unsigned char temp; |
| 166 | 165 | ||
| 167 | DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", get_pcf(adap, 1))); | 166 | DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n", |
| 167 | get_pcf(adap, 1))); | ||
| 168 | 168 | ||
| 169 | /* S1=0x80: S0 selected, serial interface off */ | 169 | /* S1=0x80: S0 selected, serial interface off */ |
| 170 | set_pcf(adap, 1, I2C_PCF_PIN); | 170 | set_pcf(adap, 1, I2C_PCF_PIN); |
| 171 | /* check to see S1 now used as R/W ctrl - | 171 | /* |
| 172 | PCF8584 does that when ESO is zero */ | 172 | * check to see S1 now used as R/W ctrl - |
| 173 | * PCF8584 does that when ESO is zero | ||
| 174 | */ | ||
| 173 | if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { | 175 | if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) { |
| 174 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); | 176 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp)); |
| 175 | return -ENXIO; /* definetly not PCF8584 */ | 177 | return -ENXIO; /* definetly not PCF8584 */ |
| 176 | } | 178 | } |
| 177 | 179 | ||
| 178 | /* load own address in S0, effective address is (own << 1) */ | 180 | /* load own address in S0, effective address is (own << 1) */ |
| 179 | i2c_outb(adap, get_own(adap)); | 181 | i2c_outb(adap, get_own(adap)); |
| 180 | /* check it's really written */ | 182 | /* check it's really written */ |
| 181 | if ((temp = i2c_inb(adap)) != get_own(adap)) { | 183 | if ((temp = i2c_inb(adap)) != get_own(adap)) { |
| @@ -183,7 +185,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
| 183 | return -ENXIO; | 185 | return -ENXIO; |
| 184 | } | 186 | } |
| 185 | 187 | ||
| 186 | /* S1=0xA0, next byte in S2 */ | 188 | /* S1=0xA0, next byte in S2 */ |
| 187 | set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); | 189 | set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1); |
| 188 | /* check to see S2 now selected */ | 190 | /* check to see S2 now selected */ |
| 189 | if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { | 191 | if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) { |
| @@ -191,7 +193,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
| 191 | return -ENXIO; | 193 | return -ENXIO; |
| 192 | } | 194 | } |
| 193 | 195 | ||
| 194 | /* load clock register S2 */ | 196 | /* load clock register S2 */ |
| 195 | i2c_outb(adap, get_clock(adap)); | 197 | i2c_outb(adap, get_clock(adap)); |
| 196 | /* check it's really written, the only 5 lowest bits does matter */ | 198 | /* check it's really written, the only 5 lowest bits does matter */ |
| 197 | if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { | 199 | if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) { |
| @@ -199,7 +201,7 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
| 199 | return -ENXIO; | 201 | return -ENXIO; |
| 200 | } | 202 | } |
| 201 | 203 | ||
| 202 | /* Enable serial interface, idle, S0 selected */ | 204 | /* Enable serial interface, idle, S0 selected */ |
| 203 | set_pcf(adap, 1, I2C_PCF_IDLE); | 205 | set_pcf(adap, 1, I2C_PCF_IDLE); |
| 204 | 206 | ||
| 205 | /* check to see PCF is really idled and we can access status register */ | 207 | /* check to see PCF is really idled and we can access status register */ |
| @@ -207,57 +209,47 @@ static int pcf_init_8584 (struct i2c_algo_pcf_data *adap) | |||
| 207 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); | 209 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp)); |
| 208 | return -ENXIO; | 210 | return -ENXIO; |
| 209 | } | 211 | } |
| 210 | 212 | ||
| 211 | printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); | 213 | printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n"); |
| 212 | 214 | ||
| 213 | return 0; | 215 | return 0; |
| 214 | } | 216 | } |
| 215 | 217 | ||
| 216 | |||
| 217 | /* ----- Utility functions | ||
| 218 | */ | ||
| 219 | |||
| 220 | static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, | 218 | static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf, |
| 221 | int count, int last) | 219 | int count, int last) |
| 222 | { | 220 | { |
| 223 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; | 221 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; |
| 224 | int wrcount, status, timeout; | 222 | int wrcount, status, timeout; |
| 225 | 223 | ||
| 226 | for (wrcount=0; wrcount<count; ++wrcount) { | 224 | for (wrcount=0; wrcount<count; ++wrcount) { |
| 227 | DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n", | 225 | DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n", |
| 228 | buf[wrcount]&0xff)); | 226 | buf[wrcount] & 0xff)); |
| 229 | i2c_outb(adap, buf[wrcount]); | 227 | i2c_outb(adap, buf[wrcount]); |
| 230 | timeout = wait_for_pin(adap, &status); | 228 | timeout = wait_for_pin(adap, &status); |
| 231 | if (timeout) { | 229 | if (timeout) { |
| 232 | if (timeout == -EINTR) { | 230 | if (timeout == -EINTR) |
| 233 | /* arbitration lost */ | 231 | return -EINTR; /* arbitration lost */ |
| 234 | return -EINTR; | 232 | |
| 235 | } | ||
| 236 | i2c_stop(adap); | 233 | i2c_stop(adap); |
| 237 | dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n"); | 234 | dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n"); |
| 238 | return -EREMOTEIO; /* got a better one ?? */ | 235 | return -EREMOTEIO; /* got a better one ?? */ |
| 239 | } | 236 | } |
| 240 | #ifndef STUB_I2C | ||
| 241 | if (status & I2C_PCF_LRB) { | 237 | if (status & I2C_PCF_LRB) { |
| 242 | i2c_stop(adap); | 238 | i2c_stop(adap); |
| 243 | dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n"); | 239 | dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n"); |
| 244 | return -EREMOTEIO; /* got a better one ?? */ | 240 | return -EREMOTEIO; /* got a better one ?? */ |
| 245 | } | 241 | } |
| 246 | #endif | ||
| 247 | } | 242 | } |
| 248 | if (last) { | 243 | if (last) |
| 249 | i2c_stop(adap); | 244 | i2c_stop(adap); |
| 250 | } | 245 | else |
| 251 | else { | ||
| 252 | i2c_repstart(adap); | 246 | i2c_repstart(adap); |
| 253 | } | ||
| 254 | 247 | ||
| 255 | return (wrcount); | 248 | return wrcount; |
| 256 | } | 249 | } |
| 257 | 250 | ||
| 258 | |||
| 259 | static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, | 251 | static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, |
| 260 | int count, int last) | 252 | int count, int last) |
| 261 | { | 253 | { |
| 262 | int i, status; | 254 | int i, status; |
| 263 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; | 255 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; |
| @@ -267,42 +259,36 @@ static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf, | |||
| 267 | for (i = 0; i <= count; i++) { | 259 | for (i = 0; i <= count; i++) { |
| 268 | 260 | ||
| 269 | if ((wfp = wait_for_pin(adap, &status))) { | 261 | if ((wfp = wait_for_pin(adap, &status))) { |
| 270 | if (wfp == -EINTR) { | 262 | if (wfp == -EINTR) |
| 271 | /* arbitration lost */ | 263 | return -EINTR; /* arbitration lost */ |
| 272 | return -EINTR; | 264 | |
| 273 | } | ||
| 274 | i2c_stop(adap); | 265 | i2c_stop(adap); |
| 275 | dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n"); | 266 | dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n"); |
| 276 | return (-1); | 267 | return -1; |
| 277 | } | 268 | } |
| 278 | 269 | ||
| 279 | #ifndef STUB_I2C | ||
| 280 | if ((status & I2C_PCF_LRB) && (i != count)) { | 270 | if ((status & I2C_PCF_LRB) && (i != count)) { |
| 281 | i2c_stop(adap); | 271 | i2c_stop(adap); |
| 282 | dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n"); | 272 | dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n"); |
| 283 | return (-1); | 273 | return -1; |
| 284 | } | 274 | } |
| 285 | #endif | 275 | |
| 286 | |||
| 287 | if (i == count - 1) { | 276 | if (i == count - 1) { |
| 288 | set_pcf(adap, 1, I2C_PCF_ESO); | 277 | set_pcf(adap, 1, I2C_PCF_ESO); |
| 289 | } else | 278 | } else if (i == count) { |
| 290 | if (i == count) { | 279 | if (last) |
| 291 | if (last) { | ||
| 292 | i2c_stop(adap); | 280 | i2c_stop(adap); |
| 293 | } else { | 281 | else |
| 294 | i2c_repstart(adap); | 282 | i2c_repstart(adap); |
| 295 | } | 283 | } |
| 296 | }; | ||
| 297 | 284 | ||
| 298 | if (i) { | 285 | if (i) |
| 299 | buf[i - 1] = i2c_inb(adap); | 286 | buf[i - 1] = i2c_inb(adap); |
| 300 | } else { | 287 | else |
| 301 | i2c_inb(adap); /* dummy read */ | 288 | i2c_inb(adap); /* dummy read */ |
| 302 | } | ||
| 303 | } | 289 | } |
| 304 | 290 | ||
| 305 | return (i - 1); | 291 | return i - 1; |
| 306 | } | 292 | } |
| 307 | 293 | ||
| 308 | 294 | ||
| @@ -323,14 +309,14 @@ static int pcf_doAddress(struct i2c_algo_pcf_data *adap, | |||
| 323 | } | 309 | } |
| 324 | 310 | ||
| 325 | static int pcf_xfer(struct i2c_adapter *i2c_adap, | 311 | static int pcf_xfer(struct i2c_adapter *i2c_adap, |
| 326 | struct i2c_msg *msgs, | 312 | struct i2c_msg *msgs, |
| 327 | int num) | 313 | int num) |
| 328 | { | 314 | { |
| 329 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; | 315 | struct i2c_algo_pcf_data *adap = i2c_adap->algo_data; |
| 330 | struct i2c_msg *pmsg; | 316 | struct i2c_msg *pmsg; |
| 331 | int i; | 317 | int i; |
| 332 | int ret=0, timeout, status; | 318 | int ret=0, timeout, status; |
| 333 | 319 | ||
| 334 | if (adap->xfer_begin) | 320 | if (adap->xfer_begin) |
| 335 | adap->xfer_begin(adap->data); | 321 | adap->xfer_begin(adap->data); |
| 336 | 322 | ||
| @@ -338,25 +324,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
| 338 | timeout = wait_for_bb(adap); | 324 | timeout = wait_for_bb(adap); |
| 339 | if (timeout) { | 325 | if (timeout) { |
| 340 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " | 326 | DEB2(printk(KERN_ERR "i2c-algo-pcf.o: " |
| 341 | "Timeout waiting for BB in pcf_xfer\n");) | 327 | "Timeout waiting for BB in pcf_xfer\n");) |
| 342 | i = -EIO; | 328 | i = -EIO; |
| 343 | goto out; | 329 | goto out; |
| 344 | } | 330 | } |
| 345 | 331 | ||
| 346 | for (i = 0;ret >= 0 && i < num; i++) { | 332 | for (i = 0;ret >= 0 && i < num; i++) { |
| 347 | pmsg = &msgs[i]; | 333 | pmsg = &msgs[i]; |
| 348 | 334 | ||
| 349 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", | 335 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n", |
| 350 | pmsg->flags & I2C_M_RD ? "read" : "write", | 336 | pmsg->flags & I2C_M_RD ? "read" : "write", |
| 351 | pmsg->len, pmsg->addr, i + 1, num);) | 337 | pmsg->len, pmsg->addr, i + 1, num);) |
| 352 | 338 | ||
| 353 | ret = pcf_doAddress(adap, pmsg); | 339 | ret = pcf_doAddress(adap, pmsg); |
| 354 | 340 | ||
| 355 | /* Send START */ | 341 | /* Send START */ |
| 356 | if (i == 0) { | 342 | if (i == 0) |
| 357 | i2c_start(adap); | 343 | i2c_start(adap); |
| 358 | } | 344 | |
| 359 | |||
| 360 | /* Wait for PIN (pending interrupt NOT) */ | 345 | /* Wait for PIN (pending interrupt NOT) */ |
| 361 | timeout = wait_for_pin(adap, &status); | 346 | timeout = wait_for_pin(adap, &status); |
| 362 | if (timeout) { | 347 | if (timeout) { |
| @@ -371,8 +356,7 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
| 371 | i = -EREMOTEIO; | 356 | i = -EREMOTEIO; |
| 372 | goto out; | 357 | goto out; |
| 373 | } | 358 | } |
| 374 | 359 | ||
| 375 | #ifndef STUB_I2C | ||
| 376 | /* Check LRB (last rcvd bit - slave ack) */ | 360 | /* Check LRB (last rcvd bit - slave ack) */ |
| 377 | if (status & I2C_PCF_LRB) { | 361 | if (status & I2C_PCF_LRB) { |
| 378 | i2c_stop(adap); | 362 | i2c_stop(adap); |
| @@ -380,27 +364,24 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
| 380 | i = -EREMOTEIO; | 364 | i = -EREMOTEIO; |
| 381 | goto out; | 365 | goto out; |
| 382 | } | 366 | } |
| 383 | #endif | 367 | |
| 384 | |||
| 385 | DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", | 368 | DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n", |
| 386 | i, msgs[i].addr, msgs[i].flags, msgs[i].len);) | 369 | i, msgs[i].addr, msgs[i].flags, msgs[i].len);) |
| 387 | 370 | ||
| 388 | /* Read */ | ||
| 389 | if (pmsg->flags & I2C_M_RD) { | 371 | if (pmsg->flags & I2C_M_RD) { |
| 390 | /* read bytes into buffer*/ | ||
| 391 | ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len, | 372 | ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len, |
| 392 | (i + 1 == num)); | 373 | (i + 1 == num)); |
| 393 | 374 | ||
| 394 | if (ret != pmsg->len) { | 375 | if (ret != pmsg->len) { |
| 395 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " | 376 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " |
| 396 | "only read %d bytes.\n",ret)); | 377 | "only read %d bytes.\n",ret)); |
| 397 | } else { | 378 | } else { |
| 398 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); | 379 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret)); |
| 399 | } | 380 | } |
| 400 | } else { /* Write */ | 381 | } else { |
| 401 | ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, | 382 | ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len, |
| 402 | (i + 1 == num)); | 383 | (i + 1 == num)); |
| 403 | 384 | ||
| 404 | if (ret != pmsg->len) { | 385 | if (ret != pmsg->len) { |
| 405 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " | 386 | DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: " |
| 406 | "only wrote %d bytes.\n",ret)); | 387 | "only wrote %d bytes.\n",ret)); |
| @@ -413,24 +394,23 @@ static int pcf_xfer(struct i2c_adapter *i2c_adap, | |||
| 413 | out: | 394 | out: |
| 414 | if (adap->xfer_end) | 395 | if (adap->xfer_end) |
| 415 | adap->xfer_end(adap->data); | 396 | adap->xfer_end(adap->data); |
| 416 | return (i); | 397 | return i; |
| 417 | } | 398 | } |
| 418 | 399 | ||
| 419 | static u32 pcf_func(struct i2c_adapter *adap) | 400 | static u32 pcf_func(struct i2c_adapter *adap) |
| 420 | { | 401 | { |
| 421 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | | 402 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | |
| 422 | I2C_FUNC_PROTOCOL_MANGLING; | 403 | I2C_FUNC_PROTOCOL_MANGLING; |
| 423 | } | 404 | } |
| 424 | 405 | ||
| 425 | /* -----exported algorithm data: ------------------------------------- */ | 406 | /* exported algorithm data: */ |
| 426 | |||
| 427 | static const struct i2c_algorithm pcf_algo = { | 407 | static const struct i2c_algorithm pcf_algo = { |
| 428 | .master_xfer = pcf_xfer, | 408 | .master_xfer = pcf_xfer, |
| 429 | .functionality = pcf_func, | 409 | .functionality = pcf_func, |
| 430 | }; | 410 | }; |
| 431 | 411 | ||
| 432 | /* | 412 | /* |
| 433 | * registering functions to load algorithms at runtime | 413 | * registering functions to load algorithms at runtime |
| 434 | */ | 414 | */ |
| 435 | int i2c_pcf_add_bus(struct i2c_adapter *adap) | 415 | int i2c_pcf_add_bus(struct i2c_adapter *adap) |
| 436 | { | 416 | { |
| @@ -458,4 +438,4 @@ MODULE_LICENSE("GPL"); | |||
| 458 | 438 | ||
| 459 | module_param(i2c_debug, int, S_IRUGO | S_IWUSR); | 439 | module_param(i2c_debug, int, S_IRUGO | S_IWUSR); |
| 460 | MODULE_PARM_DESC(i2c_debug, | 440 | MODULE_PARM_DESC(i2c_debug, |
| 461 | "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); | 441 | "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol"); |
