/* * I2C multiplexer driver for PCA9541 bus master selector * * Copyright (c) 2010 Ericsson AB. * * Author: Guenter Roeck <[email protected]> * * Derived from: * pca954x.c * * Copyright (c) 2008-2009 Rodolfo Giometti <[email protected]> * Copyright (c) 2008-2009 Eurotech S.p.A. <[email protected]> * * This file is licensed under the terms of the GNU General Public * License version 2. This program is licensed "as is" without any * warranty of any kind, whether express or implied. */ #include <linux/bitops.h> #include <linux/delay.h> #include <linux/device.h> #include <linux/i2c.h> #include <linux/i2c-mux.h> #include <linux/jiffies.h> #include <linux/module.h> #include <linux/slab.h> /* * The PCA9541 is a bus master selector. It supports two I2C masters connected * to a single slave bus. * * Before each bus transaction, a master has to acquire bus ownership. After the * transaction is complete, bus ownership has to be released. This fits well * into the I2C multiplexer framework, which provides select and release * functions for this purpose. For this reason, this driver is modeled as * single-channel I2C bus multiplexer. * * This driver assumes that the two bus masters are controlled by two different * hosts. If a single host controls both masters, platform code has to ensure * that only one of the masters is instantiated at any given time. */ #define PCA9541_CONTROL … #define PCA9541_ISTAT … #define PCA9541_CTL_MYBUS … #define PCA9541_CTL_NMYBUS … #define PCA9541_CTL_BUSON … #define PCA9541_CTL_NBUSON … #define PCA9541_CTL_BUSINIT … #define PCA9541_CTL_TESTON … #define PCA9541_CTL_NTESTON … #define PCA9541_ISTAT_INTIN … #define PCA9541_ISTAT_BUSINIT … #define PCA9541_ISTAT_BUSOK … #define PCA9541_ISTAT_BUSLOST … #define PCA9541_ISTAT_MYTEST … #define PCA9541_ISTAT_NMYTEST … #define BUSON … #define MYBUS … #define mybus(x) … #define busoff(x) … /* arbitration timeouts, in jiffies */ #define ARB_TIMEOUT … #define ARB2_TIMEOUT … /* arbitration retry delays, in us */ #define SELECT_DELAY_SHORT … #define SELECT_DELAY_LONG … struct pca9541 { … }; static const struct i2c_device_id pca9541_id[] = …; MODULE_DEVICE_TABLE(i2c, pca9541_id); #ifdef CONFIG_OF static const struct of_device_id pca9541_of_match[] = …; MODULE_DEVICE_TABLE(of, pca9541_of_match); #endif /* * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() * as they will try to lock the adapter a second time. */ static int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) { … } /* * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() * as they will try to lock adapter a second time. */ static int pca9541_reg_read(struct i2c_client *client, u8 command) { … } /* * Arbitration management functions */ /* Release bus. Also reset NTESTON and BUSINIT if it was set. */ static void pca9541_release_bus(struct i2c_client *client) { … } /* * Arbitration is defined as a two-step process. A bus master can only activate * the slave bus if it owns it; otherwise it has to request ownership first. * This multi-step process ensures that access contention is resolved * gracefully. * * Bus Ownership Other master Action * state requested access * ---------------------------------------------------- * off - yes wait for arbitration timeout or * for other master to drop request * off no no take ownership * off yes no turn on bus * on yes - done * on no - wait for arbitration timeout or * for other master to release bus * * The main contention point occurs if the slave bus is off and both masters * request ownership at the same time. In this case, one master will turn on * the slave bus, believing that it owns it. The other master will request * bus ownership. Result is that the bus is turned on, and master which did * _not_ own the slave bus before ends up owning it. */ /* Control commands per PCA9541 datasheet */ static const u8 pca9541_control[16] = …; /* * Channel arbitration * * Return values: * <0: error * 0 : bus not acquired * 1 : bus acquired */ static int pca9541_arbitrate(struct i2c_client *client) { … } static int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) { … } static int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) { … } /* * I2C init/probing/exit functions */ static int pca9541_probe(struct i2c_client *client) { … } static void pca9541_remove(struct i2c_client *client) { … } static struct i2c_driver pca9541_driver = …; module_i2c_driver(…) …; MODULE_AUTHOR(…) …; MODULE_DESCRIPTION(…) …; MODULE_LICENSE(…) …;