Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

i2c: algo: bit: allow getsda to be NULL

This is in preparation of supporting write-only SDA in i2c-gpio.

Signed-off-by: Heiner Kallweit <hkallweit1@gmail.com>
Signed-off-by: Wolfram Sang <wsa@kernel.org>

authored by

Heiner Kallweit and committed by
Wolfram Sang
9dfee148 a00bb94c

+35 -42
+35 -42
drivers/i2c/algos/i2c-algo-bit.c
··· 184 184 185 185 /* read ack: SDA should be pulled down by slave, or it may 186 186 * NAK (usually to report problems with the data we wrote). 187 + * Always report ACK if SDA is write-only. 187 188 */ 188 - ack = !getsda(adap); /* ack: sda is pulled low -> success */ 189 + ack = !adap->getsda || !getsda(adap); /* ack: sda is pulled low -> success */ 189 190 bit_dbg(2, &i2c_adap->dev, "i2c_outb: 0x%02x %s\n", (int)c, 190 191 ack ? "A" : "NA"); 191 192 ··· 239 238 return -ENODEV; 240 239 } 241 240 241 + if (adap->getsda == NULL) 242 + pr_info("%s: SDA is write-only, testing not possible\n", name); 242 243 if (adap->getscl == NULL) 243 - pr_info("%s: Testing SDA only, SCL is not readable\n", name); 244 + pr_info("%s: SCL is write-only, testing not possible\n", name); 244 245 245 - sda = getsda(adap); 246 - scl = (adap->getscl == NULL) ? 1 : getscl(adap); 246 + sda = adap->getsda ? getsda(adap) : 1; 247 + scl = adap->getscl ? getscl(adap) : 1; 247 248 if (!scl || !sda) { 248 - printk(KERN_WARNING 249 - "%s: bus seems to be busy (scl=%d, sda=%d)\n", 250 - name, scl, sda); 249 + pr_warn("%s: bus seems to be busy (scl=%d, sda=%d)\n", name, scl, sda); 251 250 goto bailout; 252 251 } 253 252 254 253 sdalo(adap); 255 - sda = getsda(adap); 256 - scl = (adap->getscl == NULL) ? 1 : getscl(adap); 257 - if (sda) { 258 - printk(KERN_WARNING "%s: SDA stuck high!\n", name); 254 + if (adap->getsda && getsda(adap)) { 255 + pr_warn("%s: SDA stuck high!\n", name); 259 256 goto bailout; 260 257 } 261 - if (!scl) { 262 - printk(KERN_WARNING 263 - "%s: SCL unexpected low while pulling SDA low!\n", 264 - name); 258 + if (adap->getscl && !getscl(adap)) { 259 + pr_warn("%s: SCL unexpected low while pulling SDA low!\n", name); 265 260 goto bailout; 266 261 } 267 262 268 263 sdahi(adap); 269 - sda = getsda(adap); 270 - scl = (adap->getscl == NULL) ? 1 : getscl(adap); 271 - if (!sda) { 272 - printk(KERN_WARNING "%s: SDA stuck low!\n", name); 264 + if (adap->getsda && !getsda(adap)) { 265 + pr_warn("%s: SDA stuck low!\n", name); 273 266 goto bailout; 274 267 } 275 - if (!scl) { 276 - printk(KERN_WARNING 277 - "%s: SCL unexpected low while pulling SDA high!\n", 278 - name); 268 + if (adap->getscl && !getscl(adap)) { 269 + pr_warn("%s: SCL unexpected low while pulling SDA high!\n", name); 279 270 goto bailout; 280 271 } 281 272 282 273 scllo(adap); 283 - sda = getsda(adap); 284 - scl = (adap->getscl == NULL) ? 0 : getscl(adap); 285 - if (scl) { 286 - printk(KERN_WARNING "%s: SCL stuck high!\n", name); 274 + if (adap->getscl && getscl(adap)) { 275 + pr_warn("%s: SCL stuck high!\n", name); 287 276 goto bailout; 288 277 } 289 - if (!sda) { 290 - printk(KERN_WARNING 291 - "%s: SDA unexpected low while pulling SCL low!\n", 292 - name); 278 + if (adap->getsda && !getsda(adap)) { 279 + pr_warn("%s: SDA unexpected low while pulling SCL low!\n", name); 293 280 goto bailout; 294 281 } 295 282 296 283 sclhi(adap); 297 - sda = getsda(adap); 298 - scl = (adap->getscl == NULL) ? 1 : getscl(adap); 299 - if (!scl) { 300 - printk(KERN_WARNING "%s: SCL stuck low!\n", name); 284 + if (adap->getscl && !getscl(adap)) { 285 + pr_warn("%s: SCL stuck low!\n", name); 301 286 goto bailout; 302 287 } 303 - if (!sda) { 304 - printk(KERN_WARNING 305 - "%s: SDA unexpected low while pulling SCL high!\n", 306 - name); 288 + if (adap->getsda && !getsda(adap)) { 289 + pr_warn("%s: SDA unexpected low while pulling SCL high!\n", name); 307 290 goto bailout; 308 291 } 309 292 ··· 405 420 unsigned char *temp = msg->buf; 406 421 int count = msg->len; 407 422 const unsigned flags = msg->flags; 423 + struct i2c_algo_bit_data *adap = i2c_adap->algo_data; 424 + 425 + if (!adap->getsda) 426 + return -EOPNOTSUPP; 408 427 409 428 while (count > 0) { 410 429 inval = i2c_inb(i2c_adap); ··· 659 670 if (ret < 0) 660 671 return ret; 661 672 662 - /* Complain if SCL can't be read */ 663 - if (bit_adap->getscl == NULL) { 673 + if (bit_adap->getsda == NULL) 674 + dev_warn(&adap->dev, "Not I2C compliant: can't read SDA\n"); 675 + 676 + if (bit_adap->getscl == NULL) 664 677 dev_warn(&adap->dev, "Not I2C compliant: can't read SCL\n"); 678 + 679 + if (bit_adap->getsda == NULL || bit_adap->getscl == NULL) 665 680 dev_warn(&adap->dev, "Bus may be unreliable\n"); 666 - } 681 + 667 682 return 0; 668 683 } 669 684