Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters
0004  *
0005  *   Copyright (C) 1995-1997 Simon G. Vogl
0006  *         1998-2000 Hans Berglund
0007  *
0008  * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
0009  * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
0010  * <mbailey@littlefeet-inc.com>
0011  *
0012  * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
0013  * messages, proper stop/repstart signaling during receive, added detect code
0014  */
0015 
0016 #include <linux/kernel.h>
0017 #include <linux/module.h>
0018 #include <linux/delay.h>
0019 #include <linux/errno.h>
0020 #include <linux/i2c.h>
0021 #include <linux/i2c-algo-pcf.h>
0022 #include "i2c-algo-pcf.h"
0023 
0024 
0025 #define DEB2(x) if (i2c_debug >= 2) x
0026 #define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */
0027 #define DEBPROTO(x) if (i2c_debug >= 9) x;
0028     /* debug the protocol by showing transferred bits */
0029 #define DEF_TIMEOUT 16
0030 
0031 /*
0032  * module parameters:
0033  */
0034 static int i2c_debug;
0035 
0036 /* setting states on the bus with the right timing: */
0037 
0038 #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
0039 #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
0040 #define get_own(adap) adap->getown(adap->data)
0041 #define get_clock(adap) adap->getclock(adap->data)
0042 #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
0043 #define i2c_inb(adap) adap->getpcf(adap->data, 0)
0044 
0045 /* other auxiliary functions */
0046 
0047 static void i2c_start(struct i2c_algo_pcf_data *adap)
0048 {
0049     DEBPROTO(printk(KERN_DEBUG "S "));
0050     set_pcf(adap, 1, I2C_PCF_START);
0051 }
0052 
0053 static void i2c_repstart(struct i2c_algo_pcf_data *adap)
0054 {
0055     DEBPROTO(printk(" Sr "));
0056     set_pcf(adap, 1, I2C_PCF_REPSTART);
0057 }
0058 
0059 static void i2c_stop(struct i2c_algo_pcf_data *adap)
0060 {
0061     DEBPROTO(printk("P\n"));
0062     set_pcf(adap, 1, I2C_PCF_STOP);
0063 }
0064 
0065 static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
0066 {
0067     DEB2(printk(KERN_INFO
0068         "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
0069         *status));
0070     /*
0071      * Cleanup from LAB -- reset and enable ESO.
0072      * This resets the PCF8584; since we've lost the bus, no
0073      * further attempts should be made by callers to clean up
0074      * (no i2c_stop() etc.)
0075      */
0076     set_pcf(adap, 1, I2C_PCF_PIN);
0077     set_pcf(adap, 1, I2C_PCF_ESO);
0078     /*
0079      * We pause for a time period sufficient for any running
0080      * I2C transaction to complete -- the arbitration logic won't
0081      * work properly until the next START is seen.
0082      * It is assumed the bus driver or client has set a proper value.
0083      *
0084      * REVISIT: should probably use msleep instead of mdelay if we
0085      * know we can sleep.
0086      */
0087     if (adap->lab_mdelay)
0088         mdelay(adap->lab_mdelay);
0089 
0090     DEB2(printk(KERN_INFO
0091         "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",
0092         get_pcf(adap, 1)));
0093 }
0094 
0095 static int wait_for_bb(struct i2c_algo_pcf_data *adap)
0096 {
0097 
0098     int timeout = DEF_TIMEOUT;
0099     int status;
0100 
0101     status = get_pcf(adap, 1);
0102 
0103     while (!(status & I2C_PCF_BB) && --timeout) {
0104         udelay(100); /* wait for 100 us */
0105         status = get_pcf(adap, 1);
0106     }
0107 
0108     if (timeout == 0) {
0109         printk(KERN_ERR "Timeout waiting for Bus Busy\n");
0110         return -ETIMEDOUT;
0111     }
0112 
0113     return 0;
0114 }
0115 
0116 static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)
0117 {
0118 
0119     int timeout = DEF_TIMEOUT;
0120 
0121     *status = get_pcf(adap, 1);
0122 
0123     while ((*status & I2C_PCF_PIN) && --timeout) {
0124         adap->waitforpin(adap->data);
0125         *status = get_pcf(adap, 1);
0126     }
0127     if (*status & I2C_PCF_LAB) {
0128         handle_lab(adap, status);
0129         return -EINTR;
0130     }
0131 
0132     if (timeout == 0)
0133         return -ETIMEDOUT;
0134 
0135     return 0;
0136 }
0137 
0138 /*
0139  * This should perform the 'PCF8584 initialization sequence' as described
0140  * in the Philips IC12 data book (1995, Aug 29).
0141  * There should be a 30 clock cycle wait after reset, I assume this
0142  * has been fulfilled.
0143  * There should be a delay at the end equal to the longest I2C message
0144  * to synchronize the BB-bit (in multimaster systems). How long is
0145  * this? I assume 1 second is always long enough.
0146  *
0147  * vdovikin: added detect code for PCF8584
0148  */
0149 static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
0150 {
0151     unsigned char temp;
0152 
0153     DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
0154                 get_pcf(adap, 1)));
0155 
0156     /* S1=0x80: S0 selected, serial interface off */
0157     set_pcf(adap, 1, I2C_PCF_PIN);
0158     /*
0159      * check to see S1 now used as R/W ctrl -
0160      * PCF8584 does that when ESO is zero
0161      */
0162     if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
0163         DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
0164         return -ENXIO; /* definitely not PCF8584 */
0165     }
0166 
0167     /* load own address in S0, effective address is (own << 1) */
0168     i2c_outb(adap, get_own(adap));
0169     /* check it's really written */
0170     if ((temp = i2c_inb(adap)) != get_own(adap)) {
0171         DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
0172         return -ENXIO;
0173     }
0174 
0175     /* S1=0xA0, next byte in S2 */
0176     set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
0177     /* check to see S2 now selected */
0178     if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
0179         DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
0180         return -ENXIO;
0181     }
0182 
0183     /* load clock register S2 */
0184     i2c_outb(adap, get_clock(adap));
0185     /* check it's really written, the only 5 lowest bits does matter */
0186     if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
0187         DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
0188         return -ENXIO;
0189     }
0190 
0191     /* Enable serial interface, idle, S0 selected */
0192     set_pcf(adap, 1, I2C_PCF_IDLE);
0193 
0194     /* check to see PCF is really idled and we can access status register */
0195     if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
0196         DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
0197         return -ENXIO;
0198     }
0199 
0200     printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
0201 
0202     return 0;
0203 }
0204 
0205 static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
0206              int count, int last)
0207 {
0208     struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
0209     int wrcount, status, timeout;
0210 
0211     for (wrcount=0; wrcount<count; ++wrcount) {
0212         DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
0213                 buf[wrcount] & 0xff));
0214         i2c_outb(adap, buf[wrcount]);
0215         timeout = wait_for_pin(adap, &status);
0216         if (timeout) {
0217             if (timeout == -EINTR)
0218                 return -EINTR; /* arbitration lost */
0219 
0220             i2c_stop(adap);
0221             dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
0222             return -EREMOTEIO; /* got a better one ?? */
0223         }
0224         if (status & I2C_PCF_LRB) {
0225             i2c_stop(adap);
0226             dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
0227             return -EREMOTEIO; /* got a better one ?? */
0228         }
0229     }
0230     if (last)
0231         i2c_stop(adap);
0232     else
0233         i2c_repstart(adap);
0234 
0235     return wrcount;
0236 }
0237 
0238 static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
0239              int count, int last)
0240 {
0241     int i, status;
0242     struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
0243     int wfp;
0244 
0245     /* increment number of bytes to read by one -- read dummy byte */
0246     for (i = 0; i <= count; i++) {
0247 
0248         if ((wfp = wait_for_pin(adap, &status))) {
0249             if (wfp == -EINTR)
0250                 return -EINTR; /* arbitration lost */
0251 
0252             i2c_stop(adap);
0253             dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
0254             return -1;
0255         }
0256 
0257         if ((status & I2C_PCF_LRB) && (i != count)) {
0258             i2c_stop(adap);
0259             dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");
0260             return -1;
0261         }
0262 
0263         if (i == count - 1) {
0264             set_pcf(adap, 1, I2C_PCF_ESO);
0265         } else if (i == count) {
0266             if (last)
0267                 i2c_stop(adap);
0268             else
0269                 i2c_repstart(adap);
0270         }
0271 
0272         if (i)
0273             buf[i - 1] = i2c_inb(adap);
0274         else
0275             i2c_inb(adap); /* dummy read */
0276     }
0277 
0278     return i - 1;
0279 }
0280 
0281 
0282 static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
0283              struct i2c_msg *msg)
0284 {
0285     unsigned char addr = i2c_8bit_addr_from_msg(msg);
0286 
0287     if (msg->flags & I2C_M_REV_DIR_ADDR)
0288         addr ^= 1;
0289     i2c_outb(adap, addr);
0290 
0291     return 0;
0292 }
0293 
0294 static int pcf_xfer(struct i2c_adapter *i2c_adap,
0295             struct i2c_msg *msgs,
0296             int num)
0297 {
0298     struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
0299     struct i2c_msg *pmsg;
0300     int i;
0301     int ret=0, timeout, status;
0302 
0303     if (adap->xfer_begin)
0304         adap->xfer_begin(adap->data);
0305 
0306     /* Check for bus busy */
0307     timeout = wait_for_bb(adap);
0308     if (timeout) {
0309         DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
0310                 "Timeout waiting for BB in pcf_xfer\n");)
0311         i = -EIO;
0312         goto out;
0313     }
0314 
0315     for (i = 0;ret >= 0 && i < num; i++) {
0316         pmsg = &msgs[i];
0317 
0318         DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
0319              pmsg->flags & I2C_M_RD ? "read" : "write",
0320              pmsg->len, pmsg->addr, i + 1, num);)
0321 
0322         ret = pcf_doAddress(adap, pmsg);
0323 
0324         /* Send START */
0325         if (i == 0)
0326             i2c_start(adap);
0327 
0328         /* Wait for PIN (pending interrupt NOT) */
0329         timeout = wait_for_pin(adap, &status);
0330         if (timeout) {
0331             if (timeout == -EINTR) {
0332                 /* arbitration lost */
0333                 i = -EINTR;
0334                 goto out;
0335             }
0336             i2c_stop(adap);
0337             DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
0338                     "for PIN(1) in pcf_xfer\n");)
0339             i = -EREMOTEIO;
0340             goto out;
0341         }
0342 
0343         /* Check LRB (last rcvd bit - slave ack) */
0344         if (status & I2C_PCF_LRB) {
0345             i2c_stop(adap);
0346             DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
0347             i = -EREMOTEIO;
0348             goto out;
0349         }
0350 
0351         DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
0352                 i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
0353 
0354         if (pmsg->flags & I2C_M_RD) {
0355             ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
0356                         (i + 1 == num));
0357 
0358             if (ret != pmsg->len) {
0359                 DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
0360                         "only read %d bytes.\n",ret));
0361             } else {
0362                 DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
0363             }
0364         } else {
0365             ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
0366                         (i + 1 == num));
0367 
0368             if (ret != pmsg->len) {
0369                 DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
0370                         "only wrote %d bytes.\n",ret));
0371             } else {
0372                 DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret));
0373             }
0374         }
0375     }
0376 
0377 out:
0378     if (adap->xfer_end)
0379         adap->xfer_end(adap->data);
0380     return i;
0381 }
0382 
0383 static u32 pcf_func(struct i2c_adapter *adap)
0384 {
0385     return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
0386            I2C_FUNC_PROTOCOL_MANGLING;
0387 }
0388 
0389 /* exported algorithm data: */
0390 static const struct i2c_algorithm pcf_algo = {
0391     .master_xfer    = pcf_xfer,
0392     .functionality  = pcf_func,
0393 };
0394 
0395 /*
0396  * registering functions to load algorithms at runtime
0397  */
0398 int i2c_pcf_add_bus(struct i2c_adapter *adap)
0399 {
0400     struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
0401     int rval;
0402 
0403     DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));
0404 
0405     /* register new adapter to i2c module... */
0406     adap->algo = &pcf_algo;
0407 
0408     if ((rval = pcf_init_8584(pcf_adap)))
0409         return rval;
0410 
0411     rval = i2c_add_adapter(adap);
0412 
0413     return rval;
0414 }
0415 EXPORT_SYMBOL(i2c_pcf_add_bus);
0416 
0417 MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
0418 MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
0419 MODULE_LICENSE("GPL");
0420 
0421 module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
0422 MODULE_PARM_DESC(i2c_debug,
0423     "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");