1*c942fddfSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
20c168cebSRoel Kluin /*
30c168cebSRoel Kluin * i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters
40c168cebSRoel Kluin *
50c168cebSRoel Kluin * Copyright (C) 1995-1997 Simon G. Vogl
60c168cebSRoel Kluin * 1998-2000 Hans Berglund
70c168cebSRoel Kluin *
80c168cebSRoel Kluin * With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi> and
90c168cebSRoel Kluin * Frodo Looijaard <frodol@dds.nl>, and also from Martin Bailey
100c168cebSRoel Kluin * <mbailey@littlefeet-inc.com>
110c168cebSRoel Kluin *
120c168cebSRoel Kluin * Partially rewriten by Oleg I. Vdovikin <vdovikin@jscc.ru> to handle multiple
130c168cebSRoel Kluin * messages, proper stop/repstart signaling during receive, added detect code
140c168cebSRoel Kluin */
151da177e4SLinus Torvalds
161da177e4SLinus Torvalds #include <linux/kernel.h>
171da177e4SLinus Torvalds #include <linux/module.h>
181da177e4SLinus Torvalds #include <linux/delay.h>
191da177e4SLinus Torvalds #include <linux/errno.h>
201da177e4SLinus Torvalds #include <linux/i2c.h>
211da177e4SLinus Torvalds #include <linux/i2c-algo-pcf.h>
221da177e4SLinus Torvalds #include "i2c-algo-pcf.h"
231da177e4SLinus Torvalds
241da177e4SLinus Torvalds
251da177e4SLinus Torvalds #define DEB2(x) if (i2c_debug >= 2) x
261da177e4SLinus Torvalds #define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */
271da177e4SLinus Torvalds #define DEBPROTO(x) if (i2c_debug >= 9) x;
281da177e4SLinus Torvalds /* debug the protocol by showing transferred bits */
291da177e4SLinus Torvalds #define DEF_TIMEOUT 16
301da177e4SLinus Torvalds
310c168cebSRoel Kluin /*
320c168cebSRoel Kluin * module parameters:
331da177e4SLinus Torvalds */
341da177e4SLinus Torvalds static int i2c_debug;
351da177e4SLinus Torvalds
360c168cebSRoel Kluin /* setting states on the bus with the right timing: */
371da177e4SLinus Torvalds
381da177e4SLinus Torvalds #define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)
391da177e4SLinus Torvalds #define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)
401da177e4SLinus Torvalds #define get_own(adap) adap->getown(adap->data)
411da177e4SLinus Torvalds #define get_clock(adap) adap->getclock(adap->data)
421da177e4SLinus Torvalds #define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)
431da177e4SLinus Torvalds #define i2c_inb(adap) adap->getpcf(adap->data, 0)
441da177e4SLinus Torvalds
450c168cebSRoel Kluin /* other auxiliary functions */
461da177e4SLinus Torvalds
i2c_start(struct i2c_algo_pcf_data * adap)471da177e4SLinus Torvalds static void i2c_start(struct i2c_algo_pcf_data *adap)
481da177e4SLinus Torvalds {
49154d22b0SFrank Seidel DEBPROTO(printk(KERN_DEBUG "S "));
501da177e4SLinus Torvalds set_pcf(adap, 1, I2C_PCF_START);
511da177e4SLinus Torvalds }
521da177e4SLinus Torvalds
i2c_repstart(struct i2c_algo_pcf_data * adap)531da177e4SLinus Torvalds static void i2c_repstart(struct i2c_algo_pcf_data *adap)
541da177e4SLinus Torvalds {
551da177e4SLinus Torvalds DEBPROTO(printk(" Sr "));
561da177e4SLinus Torvalds set_pcf(adap, 1, I2C_PCF_REPSTART);
571da177e4SLinus Torvalds }
581da177e4SLinus Torvalds
i2c_stop(struct i2c_algo_pcf_data * adap)591da177e4SLinus Torvalds static void i2c_stop(struct i2c_algo_pcf_data *adap)
601da177e4SLinus Torvalds {
611da177e4SLinus Torvalds DEBPROTO(printk("P\n"));
621da177e4SLinus Torvalds set_pcf(adap, 1, I2C_PCF_STOP);
631da177e4SLinus Torvalds }
641da177e4SLinus Torvalds
handle_lab(struct i2c_algo_pcf_data * adap,const int * status)650573d11bSEric Brower static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)
660573d11bSEric Brower {
670573d11bSEric Brower DEB2(printk(KERN_INFO
680573d11bSEric Brower "i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",
690573d11bSEric Brower *status));
700c168cebSRoel Kluin /*
710c168cebSRoel Kluin * Cleanup from LAB -- reset and enable ESO.
720573d11bSEric Brower * This resets the PCF8584; since we've lost the bus, no
730573d11bSEric Brower * further attempts should be made by callers to clean up
740573d11bSEric Brower * (no i2c_stop() etc.)
750573d11bSEric Brower */
760573d11bSEric Brower set_pcf(adap, 1, I2C_PCF_PIN);
770573d11bSEric Brower set_pcf(adap, 1, I2C_PCF_ESO);
780c168cebSRoel Kluin /*
790c168cebSRoel Kluin * We pause for a time period sufficient for any running
800573d11bSEric Brower * I2C transaction to complete -- the arbitration logic won't
810573d11bSEric Brower * work properly until the next START is seen.
820573d11bSEric Brower * It is assumed the bus driver or client has set a proper value.
830573d11bSEric Brower *
840573d11bSEric Brower * REVISIT: should probably use msleep instead of mdelay if we
850573d11bSEric Brower * know we can sleep.
860573d11bSEric Brower */
870573d11bSEric Brower if (adap->lab_mdelay)
880573d11bSEric Brower mdelay(adap->lab_mdelay);
890573d11bSEric Brower
900573d11bSEric Brower DEB2(printk(KERN_INFO
910573d11bSEric Brower "i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",
920573d11bSEric Brower get_pcf(adap, 1)));
930573d11bSEric Brower }
940573d11bSEric Brower
wait_for_bb(struct i2c_algo_pcf_data * adap)950c168cebSRoel Kluin static int wait_for_bb(struct i2c_algo_pcf_data *adap)
960c168cebSRoel Kluin {
971da177e4SLinus Torvalds
981da177e4SLinus Torvalds int timeout = DEF_TIMEOUT;
991da177e4SLinus Torvalds int status;
1001da177e4SLinus Torvalds
1011da177e4SLinus Torvalds status = get_pcf(adap, 1);
1020c168cebSRoel Kluin
10394d78e18SRoel Kluin while (!(status & I2C_PCF_BB) && --timeout) {
1041da177e4SLinus Torvalds udelay(100); /* wait for 100 us */
1051da177e4SLinus Torvalds status = get_pcf(adap, 1);
1061da177e4SLinus Torvalds }
1070c168cebSRoel Kluin
10894d78e18SRoel Kluin if (timeout == 0) {
1091da177e4SLinus Torvalds printk(KERN_ERR "Timeout waiting for Bus Busy\n");
11094d78e18SRoel Kluin return -ETIMEDOUT;
11194d78e18SRoel Kluin }
1120c168cebSRoel Kluin
11394d78e18SRoel Kluin return 0;
1141da177e4SLinus Torvalds }
1151da177e4SLinus Torvalds
wait_for_pin(struct i2c_algo_pcf_data * adap,int * status)1160c168cebSRoel Kluin static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)
1170c168cebSRoel Kluin {
1181da177e4SLinus Torvalds
1191da177e4SLinus Torvalds int timeout = DEF_TIMEOUT;
1201da177e4SLinus Torvalds
1211da177e4SLinus Torvalds *status = get_pcf(adap, 1);
1220c168cebSRoel Kluin
12394d78e18SRoel Kluin while ((*status & I2C_PCF_PIN) && --timeout) {
12408e5338dSDavid Miller adap->waitforpin(adap->data);
1251da177e4SLinus Torvalds *status = get_pcf(adap, 1);
1261da177e4SLinus Torvalds }
1271da177e4SLinus Torvalds if (*status & I2C_PCF_LAB) {
1280573d11bSEric Brower handle_lab(adap, status);
1290c168cebSRoel Kluin return -EINTR;
1301da177e4SLinus Torvalds }
1310c168cebSRoel Kluin
13294d78e18SRoel Kluin if (timeout == 0)
13394d78e18SRoel Kluin return -ETIMEDOUT;
13494d78e18SRoel Kluin
1350c168cebSRoel Kluin return 0;
1361da177e4SLinus Torvalds }
1371da177e4SLinus Torvalds
1381da177e4SLinus Torvalds /*
1391da177e4SLinus Torvalds * This should perform the 'PCF8584 initialization sequence' as described
1401da177e4SLinus Torvalds * in the Philips IC12 data book (1995, Aug 29).
1411da177e4SLinus Torvalds * There should be a 30 clock cycle wait after reset, I assume this
1421da177e4SLinus Torvalds * has been fulfilled.
1431da177e4SLinus Torvalds * There should be a delay at the end equal to the longest I2C message
1441da177e4SLinus Torvalds * to synchronize the BB-bit (in multimaster systems). How long is
1451da177e4SLinus Torvalds * this? I assume 1 second is always long enough.
1461da177e4SLinus Torvalds *
1471da177e4SLinus Torvalds * vdovikin: added detect code for PCF8584
1481da177e4SLinus Torvalds */
pcf_init_8584(struct i2c_algo_pcf_data * adap)1491da177e4SLinus Torvalds static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)
1501da177e4SLinus Torvalds {
1511da177e4SLinus Torvalds unsigned char temp;
1521da177e4SLinus Torvalds
1530c168cebSRoel Kluin DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",
1540c168cebSRoel Kluin get_pcf(adap, 1)));
1551da177e4SLinus Torvalds
1561da177e4SLinus Torvalds /* S1=0x80: S0 selected, serial interface off */
1571da177e4SLinus Torvalds set_pcf(adap, 1, I2C_PCF_PIN);
1580c168cebSRoel Kluin /*
1590c168cebSRoel Kluin * check to see S1 now used as R/W ctrl -
1600c168cebSRoel Kluin * PCF8584 does that when ESO is zero
1610c168cebSRoel Kluin */
1621da177e4SLinus Torvalds if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {
1631da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));
1647d9b48eaSUwe Kleine-König return -ENXIO; /* definitely not PCF8584 */
1651da177e4SLinus Torvalds }
1661da177e4SLinus Torvalds
1671da177e4SLinus Torvalds /* load own address in S0, effective address is (own << 1) */
1681da177e4SLinus Torvalds i2c_outb(adap, get_own(adap));
1691da177e4SLinus Torvalds /* check it's really written */
1701da177e4SLinus Torvalds if ((temp = i2c_inb(adap)) != get_own(adap)) {
1711da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));
1721da177e4SLinus Torvalds return -ENXIO;
1731da177e4SLinus Torvalds }
1741da177e4SLinus Torvalds
1751da177e4SLinus Torvalds /* S1=0xA0, next byte in S2 */
1761da177e4SLinus Torvalds set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);
1771da177e4SLinus Torvalds /* check to see S2 now selected */
1781da177e4SLinus Torvalds if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {
1791da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));
1801da177e4SLinus Torvalds return -ENXIO;
1811da177e4SLinus Torvalds }
1821da177e4SLinus Torvalds
1831da177e4SLinus Torvalds /* load clock register S2 */
1841da177e4SLinus Torvalds i2c_outb(adap, get_clock(adap));
1851da177e4SLinus Torvalds /* check it's really written, the only 5 lowest bits does matter */
1861da177e4SLinus Torvalds if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {
1871da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));
1881da177e4SLinus Torvalds return -ENXIO;
1891da177e4SLinus Torvalds }
1901da177e4SLinus Torvalds
1911da177e4SLinus Torvalds /* Enable serial interface, idle, S0 selected */
1921da177e4SLinus Torvalds set_pcf(adap, 1, I2C_PCF_IDLE);
1931da177e4SLinus Torvalds
1941da177e4SLinus Torvalds /* check to see PCF is really idled and we can access status register */
1951da177e4SLinus Torvalds if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {
1961da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));
1971da177e4SLinus Torvalds return -ENXIO;
1981da177e4SLinus Torvalds }
1991da177e4SLinus Torvalds
200a672b4c1SDavid Miller printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");
2011da177e4SLinus Torvalds
2021da177e4SLinus Torvalds return 0;
2031da177e4SLinus Torvalds }
2041da177e4SLinus Torvalds
pcf_sendbytes(struct i2c_adapter * i2c_adap,const char * buf,int count,int last)2051da177e4SLinus Torvalds static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,
2061da177e4SLinus Torvalds int count, int last)
2071da177e4SLinus Torvalds {
2081da177e4SLinus Torvalds struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
2091da177e4SLinus Torvalds int wrcount, status, timeout;
2101da177e4SLinus Torvalds
2111da177e4SLinus Torvalds for (wrcount=0; wrcount<count; ++wrcount) {
2121da177e4SLinus Torvalds DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",
2131da177e4SLinus Torvalds buf[wrcount] & 0xff));
2141da177e4SLinus Torvalds i2c_outb(adap, buf[wrcount]);
2151da177e4SLinus Torvalds timeout = wait_for_pin(adap, &status);
2161da177e4SLinus Torvalds if (timeout) {
2170c168cebSRoel Kluin if (timeout == -EINTR)
2180c168cebSRoel Kluin return -EINTR; /* arbitration lost */
2190c168cebSRoel Kluin
2201da177e4SLinus Torvalds i2c_stop(adap);
2211da177e4SLinus Torvalds dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");
2221da177e4SLinus Torvalds return -EREMOTEIO; /* got a better one ?? */
2231da177e4SLinus Torvalds }
2241da177e4SLinus Torvalds if (status & I2C_PCF_LRB) {
2251da177e4SLinus Torvalds i2c_stop(adap);
2261da177e4SLinus Torvalds dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");
2271da177e4SLinus Torvalds return -EREMOTEIO; /* got a better one ?? */
2281da177e4SLinus Torvalds }
2291da177e4SLinus Torvalds }
2300c168cebSRoel Kluin if (last)
2311da177e4SLinus Torvalds i2c_stop(adap);
2320c168cebSRoel Kluin else
2331da177e4SLinus Torvalds i2c_repstart(adap);
2341da177e4SLinus Torvalds
2350c168cebSRoel Kluin return wrcount;
2361da177e4SLinus Torvalds }
2371da177e4SLinus Torvalds
pcf_readbytes(struct i2c_adapter * i2c_adap,char * buf,int count,int last)2381da177e4SLinus Torvalds static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,
2391da177e4SLinus Torvalds int count, int last)
2401da177e4SLinus Torvalds {
2411da177e4SLinus Torvalds int i, status;
2421da177e4SLinus Torvalds struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
2431da177e4SLinus Torvalds int wfp;
2441da177e4SLinus Torvalds
2451da177e4SLinus Torvalds /* increment number of bytes to read by one -- read dummy byte */
2461da177e4SLinus Torvalds for (i = 0; i <= count; i++) {
2471da177e4SLinus Torvalds
2481da177e4SLinus Torvalds if ((wfp = wait_for_pin(adap, &status))) {
2490c168cebSRoel Kluin if (wfp == -EINTR)
2500c168cebSRoel Kluin return -EINTR; /* arbitration lost */
2510c168cebSRoel Kluin
2521da177e4SLinus Torvalds i2c_stop(adap);
2531da177e4SLinus Torvalds dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");
2540c168cebSRoel Kluin return -1;
2551da177e4SLinus Torvalds }
2561da177e4SLinus Torvalds
2571da177e4SLinus Torvalds if ((status & I2C_PCF_LRB) && (i != count)) {
2581da177e4SLinus Torvalds i2c_stop(adap);
2591da177e4SLinus Torvalds dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");
2600c168cebSRoel Kluin return -1;
2611da177e4SLinus Torvalds }
2621da177e4SLinus Torvalds
2631da177e4SLinus Torvalds if (i == count - 1) {
2641da177e4SLinus Torvalds set_pcf(adap, 1, I2C_PCF_ESO);
2650c168cebSRoel Kluin } else if (i == count) {
2660c168cebSRoel Kluin if (last)
2671da177e4SLinus Torvalds i2c_stop(adap);
2680c168cebSRoel Kluin else
2691da177e4SLinus Torvalds i2c_repstart(adap);
2701da177e4SLinus Torvalds }
2711da177e4SLinus Torvalds
2720c168cebSRoel Kluin if (i)
2731da177e4SLinus Torvalds buf[i - 1] = i2c_inb(adap);
2740c168cebSRoel Kluin else
2751da177e4SLinus Torvalds i2c_inb(adap); /* dummy read */
2761da177e4SLinus Torvalds }
2771da177e4SLinus Torvalds
2780c168cebSRoel Kluin return i - 1;
2791da177e4SLinus Torvalds }
2801da177e4SLinus Torvalds
2811da177e4SLinus Torvalds
pcf_doAddress(struct i2c_algo_pcf_data * adap,struct i2c_msg * msg)2826408a833SJean Delvare static int pcf_doAddress(struct i2c_algo_pcf_data *adap,
2836408a833SJean Delvare struct i2c_msg *msg)
2841da177e4SLinus Torvalds {
285ac6d5298SPeter Rosin unsigned char addr = i2c_8bit_addr_from_msg(msg);
2866408a833SJean Delvare
287ac6d5298SPeter Rosin if (msg->flags & I2C_M_REV_DIR_ADDR)
2881da177e4SLinus Torvalds addr ^= 1;
2891da177e4SLinus Torvalds i2c_outb(adap, addr);
2906408a833SJean Delvare
2911da177e4SLinus Torvalds return 0;
2921da177e4SLinus Torvalds }
2931da177e4SLinus Torvalds
pcf_xfer(struct i2c_adapter * i2c_adap,struct i2c_msg * msgs,int num)2941da177e4SLinus Torvalds static int pcf_xfer(struct i2c_adapter *i2c_adap,
2951da177e4SLinus Torvalds struct i2c_msg *msgs,
2961da177e4SLinus Torvalds int num)
2971da177e4SLinus Torvalds {
2981da177e4SLinus Torvalds struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;
2991da177e4SLinus Torvalds struct i2c_msg *pmsg;
3001da177e4SLinus Torvalds int i;
3011da177e4SLinus Torvalds int ret=0, timeout, status;
3021da177e4SLinus Torvalds
30330091404SDavid Miller if (adap->xfer_begin)
30430091404SDavid Miller adap->xfer_begin(adap->data);
3051da177e4SLinus Torvalds
3061da177e4SLinus Torvalds /* Check for bus busy */
3071da177e4SLinus Torvalds timeout = wait_for_bb(adap);
3081da177e4SLinus Torvalds if (timeout) {
3091da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "
3101da177e4SLinus Torvalds "Timeout waiting for BB in pcf_xfer\n");)
31130091404SDavid Miller i = -EIO;
31230091404SDavid Miller goto out;
3131da177e4SLinus Torvalds }
3141da177e4SLinus Torvalds
3151da177e4SLinus Torvalds for (i = 0;ret >= 0 && i < num; i++) {
3161da177e4SLinus Torvalds pmsg = &msgs[i];
3171da177e4SLinus Torvalds
3181da177e4SLinus Torvalds DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",
3191da177e4SLinus Torvalds pmsg->flags & I2C_M_RD ? "read" : "write",
3201da177e4SLinus Torvalds pmsg->len, pmsg->addr, i + 1, num);)
3211da177e4SLinus Torvalds
3226408a833SJean Delvare ret = pcf_doAddress(adap, pmsg);
3231da177e4SLinus Torvalds
3241da177e4SLinus Torvalds /* Send START */
3250c168cebSRoel Kluin if (i == 0)
3261da177e4SLinus Torvalds i2c_start(adap);
3271da177e4SLinus Torvalds
3281da177e4SLinus Torvalds /* Wait for PIN (pending interrupt NOT) */
3291da177e4SLinus Torvalds timeout = wait_for_pin(adap, &status);
3301da177e4SLinus Torvalds if (timeout) {
3311da177e4SLinus Torvalds if (timeout == -EINTR) {
3321da177e4SLinus Torvalds /* arbitration lost */
33330091404SDavid Miller i = -EINTR;
33430091404SDavid Miller goto out;
3351da177e4SLinus Torvalds }
3361da177e4SLinus Torvalds i2c_stop(adap);
3371da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "
3381da177e4SLinus Torvalds "for PIN(1) in pcf_xfer\n");)
33930091404SDavid Miller i = -EREMOTEIO;
34030091404SDavid Miller goto out;
3411da177e4SLinus Torvalds }
3421da177e4SLinus Torvalds
3431da177e4SLinus Torvalds /* Check LRB (last rcvd bit - slave ack) */
3441da177e4SLinus Torvalds if (status & I2C_PCF_LRB) {
3451da177e4SLinus Torvalds i2c_stop(adap);
3461da177e4SLinus Torvalds DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)
34730091404SDavid Miller i = -EREMOTEIO;
34830091404SDavid Miller goto out;
3491da177e4SLinus Torvalds }
3501da177e4SLinus Torvalds
3511da177e4SLinus Torvalds DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",
3521da177e4SLinus Torvalds i, msgs[i].addr, msgs[i].flags, msgs[i].len);)
3531da177e4SLinus Torvalds
3541da177e4SLinus Torvalds if (pmsg->flags & I2C_M_RD) {
3551da177e4SLinus Torvalds ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,
3561da177e4SLinus Torvalds (i + 1 == num));
3571da177e4SLinus Torvalds
3581da177e4SLinus Torvalds if (ret != pmsg->len) {
3591da177e4SLinus Torvalds DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
3601da177e4SLinus Torvalds "only read %d bytes.\n",ret));
3611da177e4SLinus Torvalds } else {
3621da177e4SLinus Torvalds DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));
3631da177e4SLinus Torvalds }
3640c168cebSRoel Kluin } else {
3651da177e4SLinus Torvalds ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,
3661da177e4SLinus Torvalds (i + 1 == num));
3671da177e4SLinus Torvalds
3681da177e4SLinus Torvalds if (ret != pmsg->len) {
3691da177e4SLinus Torvalds DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "
3701da177e4SLinus Torvalds "only wrote %d bytes.\n",ret));
3711da177e4SLinus Torvalds } else {
3721da177e4SLinus Torvalds DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret));
3731da177e4SLinus Torvalds }
3741da177e4SLinus Torvalds }
3751da177e4SLinus Torvalds }
3761da177e4SLinus Torvalds
37730091404SDavid Miller out:
37830091404SDavid Miller if (adap->xfer_end)
37930091404SDavid Miller adap->xfer_end(adap->data);
3800c168cebSRoel Kluin return i;
3811da177e4SLinus Torvalds }
3821da177e4SLinus Torvalds
pcf_func(struct i2c_adapter * adap)3831da177e4SLinus Torvalds static u32 pcf_func(struct i2c_adapter *adap)
3841da177e4SLinus Torvalds {
3851da177e4SLinus Torvalds return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
3866408a833SJean Delvare I2C_FUNC_PROTOCOL_MANGLING;
3871da177e4SLinus Torvalds }
3881da177e4SLinus Torvalds
3890c168cebSRoel Kluin /* exported algorithm data: */
3909e11a9fbSJean Delvare static const struct i2c_algorithm pcf_algo = {
3911da177e4SLinus Torvalds .master_xfer = pcf_xfer,
3921da177e4SLinus Torvalds .functionality = pcf_func,
3931da177e4SLinus Torvalds };
3941da177e4SLinus Torvalds
3951da177e4SLinus Torvalds /*
3961da177e4SLinus Torvalds * registering functions to load algorithms at runtime
3971da177e4SLinus Torvalds */
i2c_pcf_add_bus(struct i2c_adapter * adap)3981da177e4SLinus Torvalds int i2c_pcf_add_bus(struct i2c_adapter *adap)
3991da177e4SLinus Torvalds {
4001da177e4SLinus Torvalds struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;
4011da177e4SLinus Torvalds int rval;
4021da177e4SLinus Torvalds
4031da177e4SLinus Torvalds DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));
4041da177e4SLinus Torvalds
4051da177e4SLinus Torvalds /* register new adapter to i2c module... */
4061da177e4SLinus Torvalds adap->algo = &pcf_algo;
4071da177e4SLinus Torvalds
408b39ad0cfSMark M. Hoffman if ((rval = pcf_init_8584(pcf_adap)))
409b39ad0cfSMark M. Hoffman return rval;
410b39ad0cfSMark M. Hoffman
411b39ad0cfSMark M. Hoffman rval = i2c_add_adapter(adap);
412b39ad0cfSMark M. Hoffman
4131da177e4SLinus Torvalds return rval;
4141da177e4SLinus Torvalds }
4151da177e4SLinus Torvalds EXPORT_SYMBOL(i2c_pcf_add_bus);
4161da177e4SLinus Torvalds
4171da177e4SLinus Torvalds MODULE_AUTHOR("Hans Berglund <hb@spacetec.no>");
4181da177e4SLinus Torvalds MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");
4191da177e4SLinus Torvalds MODULE_LICENSE("GPL");
4201da177e4SLinus Torvalds
4211da177e4SLinus Torvalds module_param(i2c_debug, int, S_IRUGO | S_IWUSR);
4221da177e4SLinus Torvalds MODULE_PARM_DESC(i2c_debug,
4231da177e4SLinus Torvalds "debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");
424