Path: blob/master/drivers/i2c/algos/i2c-algo-pcf.c
17548 views
/*1* i2c-algo-pcf.c i2c driver algorithms for PCF8584 adapters2*3* Copyright (C) 1995-1997 Simon G. Vogl4* 1998-2000 Hans Berglund5*6* This program is free software; you can redistribute it and/or modify7* it under the terms of the GNU General Public License as published by8* the Free Software Foundation; either version 2 of the License, or9* (at your option) any later version.10*11* This program is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the14* GNU General Public License for more details.15*16* You should have received a copy of the GNU General Public License17* along with this program; if not, write to the Free Software18* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.19*20* With some changes from Kyösti Mälkki <[email protected]> and21* Frodo Looijaard <[email protected]>, and also from Martin Bailey22* <[email protected]>23*24* Partially rewriten by Oleg I. Vdovikin <[email protected]> to handle multiple25* messages, proper stop/repstart signaling during receive, added detect code26*/2728#include <linux/kernel.h>29#include <linux/module.h>30#include <linux/delay.h>31#include <linux/init.h>32#include <linux/errno.h>33#include <linux/i2c.h>34#include <linux/i2c-algo-pcf.h>35#include "i2c-algo-pcf.h"363738#define DEB2(x) if (i2c_debug >= 2) x39#define DEB3(x) if (i2c_debug >= 3) x /* print several statistical values */40#define DEBPROTO(x) if (i2c_debug >= 9) x;41/* debug the protocol by showing transferred bits */42#define DEF_TIMEOUT 164344/*45* module parameters:46*/47static int i2c_debug;4849/* setting states on the bus with the right timing: */5051#define set_pcf(adap, ctl, val) adap->setpcf(adap->data, ctl, val)52#define get_pcf(adap, ctl) adap->getpcf(adap->data, ctl)53#define get_own(adap) adap->getown(adap->data)54#define get_clock(adap) adap->getclock(adap->data)55#define i2c_outb(adap, val) adap->setpcf(adap->data, 0, val)56#define i2c_inb(adap) adap->getpcf(adap->data, 0)5758/* other auxiliary functions */5960static void i2c_start(struct i2c_algo_pcf_data *adap)61{62DEBPROTO(printk(KERN_DEBUG "S "));63set_pcf(adap, 1, I2C_PCF_START);64}6566static void i2c_repstart(struct i2c_algo_pcf_data *adap)67{68DEBPROTO(printk(" Sr "));69set_pcf(adap, 1, I2C_PCF_REPSTART);70}7172static void i2c_stop(struct i2c_algo_pcf_data *adap)73{74DEBPROTO(printk("P\n"));75set_pcf(adap, 1, I2C_PCF_STOP);76}7778static void handle_lab(struct i2c_algo_pcf_data *adap, const int *status)79{80DEB2(printk(KERN_INFO81"i2c-algo-pcf.o: lost arbitration (CSR 0x%02x)\n",82*status));83/*84* Cleanup from LAB -- reset and enable ESO.85* This resets the PCF8584; since we've lost the bus, no86* further attempts should be made by callers to clean up87* (no i2c_stop() etc.)88*/89set_pcf(adap, 1, I2C_PCF_PIN);90set_pcf(adap, 1, I2C_PCF_ESO);91/*92* We pause for a time period sufficient for any running93* I2C transaction to complete -- the arbitration logic won't94* work properly until the next START is seen.95* It is assumed the bus driver or client has set a proper value.96*97* REVISIT: should probably use msleep instead of mdelay if we98* know we can sleep.99*/100if (adap->lab_mdelay)101mdelay(adap->lab_mdelay);102103DEB2(printk(KERN_INFO104"i2c-algo-pcf.o: reset LAB condition (CSR 0x%02x)\n",105get_pcf(adap, 1)));106}107108static int wait_for_bb(struct i2c_algo_pcf_data *adap)109{110111int timeout = DEF_TIMEOUT;112int status;113114status = get_pcf(adap, 1);115116while (!(status & I2C_PCF_BB) && --timeout) {117udelay(100); /* wait for 100 us */118status = get_pcf(adap, 1);119}120121if (timeout == 0) {122printk(KERN_ERR "Timeout waiting for Bus Busy\n");123return -ETIMEDOUT;124}125126return 0;127}128129static int wait_for_pin(struct i2c_algo_pcf_data *adap, int *status)130{131132int timeout = DEF_TIMEOUT;133134*status = get_pcf(adap, 1);135136while ((*status & I2C_PCF_PIN) && --timeout) {137adap->waitforpin(adap->data);138*status = get_pcf(adap, 1);139}140if (*status & I2C_PCF_LAB) {141handle_lab(adap, status);142return -EINTR;143}144145if (timeout == 0)146return -ETIMEDOUT;147148return 0;149}150151/*152* This should perform the 'PCF8584 initialization sequence' as described153* in the Philips IC12 data book (1995, Aug 29).154* There should be a 30 clock cycle wait after reset, I assume this155* has been fulfilled.156* There should be a delay at the end equal to the longest I2C message157* to synchronize the BB-bit (in multimaster systems). How long is158* this? I assume 1 second is always long enough.159*160* vdovikin: added detect code for PCF8584161*/162static int pcf_init_8584 (struct i2c_algo_pcf_data *adap)163{164unsigned char temp;165166DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: PCF state 0x%02x\n",167get_pcf(adap, 1)));168169/* S1=0x80: S0 selected, serial interface off */170set_pcf(adap, 1, I2C_PCF_PIN);171/*172* check to see S1 now used as R/W ctrl -173* PCF8584 does that when ESO is zero174*/175if (((temp = get_pcf(adap, 1)) & 0x7f) != (0)) {176DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S0 (0x%02x).\n", temp));177return -ENXIO; /* definitely not PCF8584 */178}179180/* load own address in S0, effective address is (own << 1) */181i2c_outb(adap, get_own(adap));182/* check it's really written */183if ((temp = i2c_inb(adap)) != get_own(adap)) {184DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S0 (0x%02x).\n", temp));185return -ENXIO;186}187188/* S1=0xA0, next byte in S2 */189set_pcf(adap, 1, I2C_PCF_PIN | I2C_PCF_ES1);190/* check to see S2 now selected */191if (((temp = get_pcf(adap, 1)) & 0x7f) != I2C_PCF_ES1) {192DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S2 (0x%02x).\n", temp));193return -ENXIO;194}195196/* load clock register S2 */197i2c_outb(adap, get_clock(adap));198/* check it's really written, the only 5 lowest bits does matter */199if (((temp = i2c_inb(adap)) & 0x1f) != get_clock(adap)) {200DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't set S2 (0x%02x).\n", temp));201return -ENXIO;202}203204/* Enable serial interface, idle, S0 selected */205set_pcf(adap, 1, I2C_PCF_IDLE);206207/* check to see PCF is really idled and we can access status register */208if ((temp = get_pcf(adap, 1)) != (I2C_PCF_PIN | I2C_PCF_BB)) {209DEB2(printk(KERN_ERR "i2c-algo-pcf.o: PCF detection failed -- can't select S1` (0x%02x).\n", temp));210return -ENXIO;211}212213printk(KERN_DEBUG "i2c-algo-pcf.o: detected and initialized PCF8584.\n");214215return 0;216}217218static int pcf_sendbytes(struct i2c_adapter *i2c_adap, const char *buf,219int count, int last)220{221struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;222int wrcount, status, timeout;223224for (wrcount=0; wrcount<count; ++wrcount) {225DEB2(dev_dbg(&i2c_adap->dev, "i2c_write: writing %2.2X\n",226buf[wrcount] & 0xff));227i2c_outb(adap, buf[wrcount]);228timeout = wait_for_pin(adap, &status);229if (timeout) {230if (timeout == -EINTR)231return -EINTR; /* arbitration lost */232233i2c_stop(adap);234dev_err(&i2c_adap->dev, "i2c_write: error - timeout.\n");235return -EREMOTEIO; /* got a better one ?? */236}237if (status & I2C_PCF_LRB) {238i2c_stop(adap);239dev_err(&i2c_adap->dev, "i2c_write: error - no ack.\n");240return -EREMOTEIO; /* got a better one ?? */241}242}243if (last)244i2c_stop(adap);245else246i2c_repstart(adap);247248return wrcount;249}250251static int pcf_readbytes(struct i2c_adapter *i2c_adap, char *buf,252int count, int last)253{254int i, status;255struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;256int wfp;257258/* increment number of bytes to read by one -- read dummy byte */259for (i = 0; i <= count; i++) {260261if ((wfp = wait_for_pin(adap, &status))) {262if (wfp == -EINTR)263return -EINTR; /* arbitration lost */264265i2c_stop(adap);266dev_err(&i2c_adap->dev, "pcf_readbytes timed out.\n");267return -1;268}269270if ((status & I2C_PCF_LRB) && (i != count)) {271i2c_stop(adap);272dev_err(&i2c_adap->dev, "i2c_read: i2c_inb, No ack.\n");273return -1;274}275276if (i == count - 1) {277set_pcf(adap, 1, I2C_PCF_ESO);278} else if (i == count) {279if (last)280i2c_stop(adap);281else282i2c_repstart(adap);283}284285if (i)286buf[i - 1] = i2c_inb(adap);287else288i2c_inb(adap); /* dummy read */289}290291return i - 1;292}293294295static int pcf_doAddress(struct i2c_algo_pcf_data *adap,296struct i2c_msg *msg)297{298unsigned short flags = msg->flags;299unsigned char addr;300301addr = msg->addr << 1;302if (flags & I2C_M_RD)303addr |= 1;304if (flags & I2C_M_REV_DIR_ADDR)305addr ^= 1;306i2c_outb(adap, addr);307308return 0;309}310311static int pcf_xfer(struct i2c_adapter *i2c_adap,312struct i2c_msg *msgs,313int num)314{315struct i2c_algo_pcf_data *adap = i2c_adap->algo_data;316struct i2c_msg *pmsg;317int i;318int ret=0, timeout, status;319320if (adap->xfer_begin)321adap->xfer_begin(adap->data);322323/* Check for bus busy */324timeout = wait_for_bb(adap);325if (timeout) {326DEB2(printk(KERN_ERR "i2c-algo-pcf.o: "327"Timeout waiting for BB in pcf_xfer\n");)328i = -EIO;329goto out;330}331332for (i = 0;ret >= 0 && i < num; i++) {333pmsg = &msgs[i];334335DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: Doing %s %d bytes to 0x%02x - %d of %d messages\n",336pmsg->flags & I2C_M_RD ? "read" : "write",337pmsg->len, pmsg->addr, i + 1, num);)338339ret = pcf_doAddress(adap, pmsg);340341/* Send START */342if (i == 0)343i2c_start(adap);344345/* Wait for PIN (pending interrupt NOT) */346timeout = wait_for_pin(adap, &status);347if (timeout) {348if (timeout == -EINTR) {349/* arbitration lost */350i = -EINTR;351goto out;352}353i2c_stop(adap);354DEB2(printk(KERN_ERR "i2c-algo-pcf.o: Timeout waiting "355"for PIN(1) in pcf_xfer\n");)356i = -EREMOTEIO;357goto out;358}359360/* Check LRB (last rcvd bit - slave ack) */361if (status & I2C_PCF_LRB) {362i2c_stop(adap);363DEB2(printk(KERN_ERR "i2c-algo-pcf.o: No LRB(1) in pcf_xfer\n");)364i = -EREMOTEIO;365goto out;366}367368DEB3(printk(KERN_DEBUG "i2c-algo-pcf.o: Msg %d, addr=0x%x, flags=0x%x, len=%d\n",369i, msgs[i].addr, msgs[i].flags, msgs[i].len);)370371if (pmsg->flags & I2C_M_RD) {372ret = pcf_readbytes(i2c_adap, pmsg->buf, pmsg->len,373(i + 1 == num));374375if (ret != pmsg->len) {376DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "377"only read %d bytes.\n",ret));378} else {379DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: read %d bytes.\n",ret));380}381} else {382ret = pcf_sendbytes(i2c_adap, pmsg->buf, pmsg->len,383(i + 1 == num));384385if (ret != pmsg->len) {386DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: fail: "387"only wrote %d bytes.\n",ret));388} else {389DEB2(printk(KERN_DEBUG "i2c-algo-pcf.o: wrote %d bytes.\n",ret));390}391}392}393394out:395if (adap->xfer_end)396adap->xfer_end(adap->data);397return i;398}399400static u32 pcf_func(struct i2c_adapter *adap)401{402return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |403I2C_FUNC_PROTOCOL_MANGLING;404}405406/* exported algorithm data: */407static const struct i2c_algorithm pcf_algo = {408.master_xfer = pcf_xfer,409.functionality = pcf_func,410};411412/*413* registering functions to load algorithms at runtime414*/415int i2c_pcf_add_bus(struct i2c_adapter *adap)416{417struct i2c_algo_pcf_data *pcf_adap = adap->algo_data;418int rval;419420DEB2(dev_dbg(&adap->dev, "hw routines registered.\n"));421422/* register new adapter to i2c module... */423adap->algo = &pcf_algo;424425if ((rval = pcf_init_8584(pcf_adap)))426return rval;427428rval = i2c_add_adapter(adap);429430return rval;431}432EXPORT_SYMBOL(i2c_pcf_add_bus);433434MODULE_AUTHOR("Hans Berglund <[email protected]>");435MODULE_DESCRIPTION("I2C-Bus PCF8584 algorithm");436MODULE_LICENSE("GPL");437438module_param(i2c_debug, int, S_IRUGO | S_IWUSR);439MODULE_PARM_DESC(i2c_debug,440"debug level - 0 off; 1 normal; 2,3 more verbose; 9 pcf-protocol");441442443