162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci * I2C multiplexer driver for PCA9541 bus master selector 362306a36Sopenharmony_ci * 462306a36Sopenharmony_ci * Copyright (c) 2010 Ericsson AB. 562306a36Sopenharmony_ci * 662306a36Sopenharmony_ci * Author: Guenter Roeck <linux@roeck-us.net> 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Derived from: 962306a36Sopenharmony_ci * pca954x.c 1062306a36Sopenharmony_ci * 1162306a36Sopenharmony_ci * Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it> 1262306a36Sopenharmony_ci * Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it> 1362306a36Sopenharmony_ci * 1462306a36Sopenharmony_ci * This file is licensed under the terms of the GNU General Public 1562306a36Sopenharmony_ci * License version 2. This program is licensed "as is" without any 1662306a36Sopenharmony_ci * warranty of any kind, whether express or implied. 1762306a36Sopenharmony_ci */ 1862306a36Sopenharmony_ci 1962306a36Sopenharmony_ci#include <linux/bitops.h> 2062306a36Sopenharmony_ci#include <linux/delay.h> 2162306a36Sopenharmony_ci#include <linux/device.h> 2262306a36Sopenharmony_ci#include <linux/i2c.h> 2362306a36Sopenharmony_ci#include <linux/i2c-mux.h> 2462306a36Sopenharmony_ci#include <linux/jiffies.h> 2562306a36Sopenharmony_ci#include <linux/module.h> 2662306a36Sopenharmony_ci#include <linux/slab.h> 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci/* 2962306a36Sopenharmony_ci * The PCA9541 is a bus master selector. It supports two I2C masters connected 3062306a36Sopenharmony_ci * to a single slave bus. 3162306a36Sopenharmony_ci * 3262306a36Sopenharmony_ci * Before each bus transaction, a master has to acquire bus ownership. After the 3362306a36Sopenharmony_ci * transaction is complete, bus ownership has to be released. This fits well 3462306a36Sopenharmony_ci * into the I2C multiplexer framework, which provides select and release 3562306a36Sopenharmony_ci * functions for this purpose. For this reason, this driver is modeled as 3662306a36Sopenharmony_ci * single-channel I2C bus multiplexer. 3762306a36Sopenharmony_ci * 3862306a36Sopenharmony_ci * This driver assumes that the two bus masters are controlled by two different 3962306a36Sopenharmony_ci * hosts. If a single host controls both masters, platform code has to ensure 4062306a36Sopenharmony_ci * that only one of the masters is instantiated at any given time. 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci#define PCA9541_CONTROL 0x01 4462306a36Sopenharmony_ci#define PCA9541_ISTAT 0x02 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci#define PCA9541_CTL_MYBUS BIT(0) 4762306a36Sopenharmony_ci#define PCA9541_CTL_NMYBUS BIT(1) 4862306a36Sopenharmony_ci#define PCA9541_CTL_BUSON BIT(2) 4962306a36Sopenharmony_ci#define PCA9541_CTL_NBUSON BIT(3) 5062306a36Sopenharmony_ci#define PCA9541_CTL_BUSINIT BIT(4) 5162306a36Sopenharmony_ci#define PCA9541_CTL_TESTON BIT(6) 5262306a36Sopenharmony_ci#define PCA9541_CTL_NTESTON BIT(7) 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci#define PCA9541_ISTAT_INTIN BIT(0) 5562306a36Sopenharmony_ci#define PCA9541_ISTAT_BUSINIT BIT(1) 5662306a36Sopenharmony_ci#define PCA9541_ISTAT_BUSOK BIT(2) 5762306a36Sopenharmony_ci#define PCA9541_ISTAT_BUSLOST BIT(3) 5862306a36Sopenharmony_ci#define PCA9541_ISTAT_MYTEST BIT(6) 5962306a36Sopenharmony_ci#define PCA9541_ISTAT_NMYTEST BIT(7) 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci#define BUSON (PCA9541_CTL_BUSON | PCA9541_CTL_NBUSON) 6262306a36Sopenharmony_ci#define MYBUS (PCA9541_CTL_MYBUS | PCA9541_CTL_NMYBUS) 6362306a36Sopenharmony_ci#define mybus(x) (!((x) & MYBUS) || ((x) & MYBUS) == MYBUS) 6462306a36Sopenharmony_ci#define busoff(x) (!((x) & BUSON) || ((x) & BUSON) == BUSON) 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci/* arbitration timeouts, in jiffies */ 6762306a36Sopenharmony_ci#define ARB_TIMEOUT (HZ / 8) /* 125 ms until forcing bus ownership */ 6862306a36Sopenharmony_ci#define ARB2_TIMEOUT (HZ / 4) /* 250 ms until acquisition failure */ 6962306a36Sopenharmony_ci 7062306a36Sopenharmony_ci/* arbitration retry delays, in us */ 7162306a36Sopenharmony_ci#define SELECT_DELAY_SHORT 50 7262306a36Sopenharmony_ci#define SELECT_DELAY_LONG 1000 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_cistruct pca9541 { 7562306a36Sopenharmony_ci struct i2c_client *client; 7662306a36Sopenharmony_ci unsigned long select_timeout; 7762306a36Sopenharmony_ci unsigned long arb_timeout; 7862306a36Sopenharmony_ci}; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_cistatic const struct i2c_device_id pca9541_id[] = { 8162306a36Sopenharmony_ci {"pca9541", 0}, 8262306a36Sopenharmony_ci {} 8362306a36Sopenharmony_ci}; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ciMODULE_DEVICE_TABLE(i2c, pca9541_id); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci#ifdef CONFIG_OF 8862306a36Sopenharmony_cistatic const struct of_device_id pca9541_of_match[] = { 8962306a36Sopenharmony_ci { .compatible = "nxp,pca9541" }, 9062306a36Sopenharmony_ci {} 9162306a36Sopenharmony_ci}; 9262306a36Sopenharmony_ciMODULE_DEVICE_TABLE(of, pca9541_of_match); 9362306a36Sopenharmony_ci#endif 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci/* 9662306a36Sopenharmony_ci * Write to chip register. Don't use i2c_transfer()/i2c_smbus_xfer() 9762306a36Sopenharmony_ci * as they will try to lock the adapter a second time. 9862306a36Sopenharmony_ci */ 9962306a36Sopenharmony_cistatic int pca9541_reg_write(struct i2c_client *client, u8 command, u8 val) 10062306a36Sopenharmony_ci{ 10162306a36Sopenharmony_ci struct i2c_adapter *adap = client->adapter; 10262306a36Sopenharmony_ci union i2c_smbus_data data = { .byte = val }; 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci return __i2c_smbus_xfer(adap, client->addr, client->flags, 10562306a36Sopenharmony_ci I2C_SMBUS_WRITE, command, 10662306a36Sopenharmony_ci I2C_SMBUS_BYTE_DATA, &data); 10762306a36Sopenharmony_ci} 10862306a36Sopenharmony_ci 10962306a36Sopenharmony_ci/* 11062306a36Sopenharmony_ci * Read from chip register. Don't use i2c_transfer()/i2c_smbus_xfer() 11162306a36Sopenharmony_ci * as they will try to lock adapter a second time. 11262306a36Sopenharmony_ci */ 11362306a36Sopenharmony_cistatic int pca9541_reg_read(struct i2c_client *client, u8 command) 11462306a36Sopenharmony_ci{ 11562306a36Sopenharmony_ci struct i2c_adapter *adap = client->adapter; 11662306a36Sopenharmony_ci union i2c_smbus_data data; 11762306a36Sopenharmony_ci int ret; 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci ret = __i2c_smbus_xfer(adap, client->addr, client->flags, 12062306a36Sopenharmony_ci I2C_SMBUS_READ, command, 12162306a36Sopenharmony_ci I2C_SMBUS_BYTE_DATA, &data); 12262306a36Sopenharmony_ci 12362306a36Sopenharmony_ci return ret ?: data.byte; 12462306a36Sopenharmony_ci} 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci/* 12762306a36Sopenharmony_ci * Arbitration management functions 12862306a36Sopenharmony_ci */ 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci/* Release bus. Also reset NTESTON and BUSINIT if it was set. */ 13162306a36Sopenharmony_cistatic void pca9541_release_bus(struct i2c_client *client) 13262306a36Sopenharmony_ci{ 13362306a36Sopenharmony_ci int reg; 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci reg = pca9541_reg_read(client, PCA9541_CONTROL); 13662306a36Sopenharmony_ci if (reg >= 0 && !busoff(reg) && mybus(reg)) 13762306a36Sopenharmony_ci pca9541_reg_write(client, PCA9541_CONTROL, 13862306a36Sopenharmony_ci (reg & PCA9541_CTL_NBUSON) >> 1); 13962306a36Sopenharmony_ci} 14062306a36Sopenharmony_ci 14162306a36Sopenharmony_ci/* 14262306a36Sopenharmony_ci * Arbitration is defined as a two-step process. A bus master can only activate 14362306a36Sopenharmony_ci * the slave bus if it owns it; otherwise it has to request ownership first. 14462306a36Sopenharmony_ci * This multi-step process ensures that access contention is resolved 14562306a36Sopenharmony_ci * gracefully. 14662306a36Sopenharmony_ci * 14762306a36Sopenharmony_ci * Bus Ownership Other master Action 14862306a36Sopenharmony_ci * state requested access 14962306a36Sopenharmony_ci * ---------------------------------------------------- 15062306a36Sopenharmony_ci * off - yes wait for arbitration timeout or 15162306a36Sopenharmony_ci * for other master to drop request 15262306a36Sopenharmony_ci * off no no take ownership 15362306a36Sopenharmony_ci * off yes no turn on bus 15462306a36Sopenharmony_ci * on yes - done 15562306a36Sopenharmony_ci * on no - wait for arbitration timeout or 15662306a36Sopenharmony_ci * for other master to release bus 15762306a36Sopenharmony_ci * 15862306a36Sopenharmony_ci * The main contention point occurs if the slave bus is off and both masters 15962306a36Sopenharmony_ci * request ownership at the same time. In this case, one master will turn on 16062306a36Sopenharmony_ci * the slave bus, believing that it owns it. The other master will request 16162306a36Sopenharmony_ci * bus ownership. Result is that the bus is turned on, and master which did 16262306a36Sopenharmony_ci * _not_ own the slave bus before ends up owning it. 16362306a36Sopenharmony_ci */ 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_ci/* Control commands per PCA9541 datasheet */ 16662306a36Sopenharmony_cistatic const u8 pca9541_control[16] = { 16762306a36Sopenharmony_ci 4, 0, 1, 5, 4, 4, 5, 5, 0, 0, 1, 1, 0, 4, 5, 1 16862306a36Sopenharmony_ci}; 16962306a36Sopenharmony_ci 17062306a36Sopenharmony_ci/* 17162306a36Sopenharmony_ci * Channel arbitration 17262306a36Sopenharmony_ci * 17362306a36Sopenharmony_ci * Return values: 17462306a36Sopenharmony_ci * <0: error 17562306a36Sopenharmony_ci * 0 : bus not acquired 17662306a36Sopenharmony_ci * 1 : bus acquired 17762306a36Sopenharmony_ci */ 17862306a36Sopenharmony_cistatic int pca9541_arbitrate(struct i2c_client *client) 17962306a36Sopenharmony_ci{ 18062306a36Sopenharmony_ci struct i2c_mux_core *muxc = i2c_get_clientdata(client); 18162306a36Sopenharmony_ci struct pca9541 *data = i2c_mux_priv(muxc); 18262306a36Sopenharmony_ci int reg; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci reg = pca9541_reg_read(client, PCA9541_CONTROL); 18562306a36Sopenharmony_ci if (reg < 0) 18662306a36Sopenharmony_ci return reg; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci if (busoff(reg)) { 18962306a36Sopenharmony_ci int istat; 19062306a36Sopenharmony_ci /* 19162306a36Sopenharmony_ci * Bus is off. Request ownership or turn it on unless 19262306a36Sopenharmony_ci * other master requested ownership. 19362306a36Sopenharmony_ci */ 19462306a36Sopenharmony_ci istat = pca9541_reg_read(client, PCA9541_ISTAT); 19562306a36Sopenharmony_ci if (!(istat & PCA9541_ISTAT_NMYTEST) 19662306a36Sopenharmony_ci || time_is_before_eq_jiffies(data->arb_timeout)) { 19762306a36Sopenharmony_ci /* 19862306a36Sopenharmony_ci * Other master did not request ownership, 19962306a36Sopenharmony_ci * or arbitration timeout expired. Take the bus. 20062306a36Sopenharmony_ci */ 20162306a36Sopenharmony_ci pca9541_reg_write(client, 20262306a36Sopenharmony_ci PCA9541_CONTROL, 20362306a36Sopenharmony_ci pca9541_control[reg & 0x0f] 20462306a36Sopenharmony_ci | PCA9541_CTL_NTESTON); 20562306a36Sopenharmony_ci data->select_timeout = SELECT_DELAY_SHORT; 20662306a36Sopenharmony_ci } else { 20762306a36Sopenharmony_ci /* 20862306a36Sopenharmony_ci * Other master requested ownership. 20962306a36Sopenharmony_ci * Set extra long timeout to give it time to acquire it. 21062306a36Sopenharmony_ci */ 21162306a36Sopenharmony_ci data->select_timeout = SELECT_DELAY_LONG * 2; 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci } else if (mybus(reg)) { 21462306a36Sopenharmony_ci /* 21562306a36Sopenharmony_ci * Bus is on, and we own it. We are done with acquisition. 21662306a36Sopenharmony_ci * Reset NTESTON and BUSINIT, then return success. 21762306a36Sopenharmony_ci */ 21862306a36Sopenharmony_ci if (reg & (PCA9541_CTL_NTESTON | PCA9541_CTL_BUSINIT)) 21962306a36Sopenharmony_ci pca9541_reg_write(client, 22062306a36Sopenharmony_ci PCA9541_CONTROL, 22162306a36Sopenharmony_ci reg & ~(PCA9541_CTL_NTESTON 22262306a36Sopenharmony_ci | PCA9541_CTL_BUSINIT)); 22362306a36Sopenharmony_ci return 1; 22462306a36Sopenharmony_ci } else { 22562306a36Sopenharmony_ci /* 22662306a36Sopenharmony_ci * Other master owns the bus. 22762306a36Sopenharmony_ci * If arbitration timeout has expired, force ownership. 22862306a36Sopenharmony_ci * Otherwise request it. 22962306a36Sopenharmony_ci */ 23062306a36Sopenharmony_ci data->select_timeout = SELECT_DELAY_LONG; 23162306a36Sopenharmony_ci if (time_is_before_eq_jiffies(data->arb_timeout)) { 23262306a36Sopenharmony_ci /* Time is up, take the bus and reset it. */ 23362306a36Sopenharmony_ci pca9541_reg_write(client, 23462306a36Sopenharmony_ci PCA9541_CONTROL, 23562306a36Sopenharmony_ci pca9541_control[reg & 0x0f] 23662306a36Sopenharmony_ci | PCA9541_CTL_BUSINIT 23762306a36Sopenharmony_ci | PCA9541_CTL_NTESTON); 23862306a36Sopenharmony_ci } else { 23962306a36Sopenharmony_ci /* Request bus ownership if needed */ 24062306a36Sopenharmony_ci if (!(reg & PCA9541_CTL_NTESTON)) 24162306a36Sopenharmony_ci pca9541_reg_write(client, 24262306a36Sopenharmony_ci PCA9541_CONTROL, 24362306a36Sopenharmony_ci reg | PCA9541_CTL_NTESTON); 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci } 24662306a36Sopenharmony_ci return 0; 24762306a36Sopenharmony_ci} 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_cistatic int pca9541_select_chan(struct i2c_mux_core *muxc, u32 chan) 25062306a36Sopenharmony_ci{ 25162306a36Sopenharmony_ci struct pca9541 *data = i2c_mux_priv(muxc); 25262306a36Sopenharmony_ci struct i2c_client *client = data->client; 25362306a36Sopenharmony_ci int ret; 25462306a36Sopenharmony_ci unsigned long timeout = jiffies + ARB2_TIMEOUT; 25562306a36Sopenharmony_ci /* give up after this time */ 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci data->arb_timeout = jiffies + ARB_TIMEOUT; 25862306a36Sopenharmony_ci /* force bus ownership after this time */ 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci do { 26162306a36Sopenharmony_ci ret = pca9541_arbitrate(client); 26262306a36Sopenharmony_ci if (ret) 26362306a36Sopenharmony_ci return ret < 0 ? ret : 0; 26462306a36Sopenharmony_ci 26562306a36Sopenharmony_ci if (data->select_timeout == SELECT_DELAY_SHORT) 26662306a36Sopenharmony_ci udelay(data->select_timeout); 26762306a36Sopenharmony_ci else 26862306a36Sopenharmony_ci msleep(data->select_timeout / 1000); 26962306a36Sopenharmony_ci } while (time_is_after_eq_jiffies(timeout)); 27062306a36Sopenharmony_ci 27162306a36Sopenharmony_ci return -ETIMEDOUT; 27262306a36Sopenharmony_ci} 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_cistatic int pca9541_release_chan(struct i2c_mux_core *muxc, u32 chan) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci struct pca9541 *data = i2c_mux_priv(muxc); 27762306a36Sopenharmony_ci struct i2c_client *client = data->client; 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci pca9541_release_bus(client); 28062306a36Sopenharmony_ci return 0; 28162306a36Sopenharmony_ci} 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci/* 28462306a36Sopenharmony_ci * I2C init/probing/exit functions 28562306a36Sopenharmony_ci */ 28662306a36Sopenharmony_cistatic int pca9541_probe(struct i2c_client *client) 28762306a36Sopenharmony_ci{ 28862306a36Sopenharmony_ci struct i2c_adapter *adap = client->adapter; 28962306a36Sopenharmony_ci struct i2c_mux_core *muxc; 29062306a36Sopenharmony_ci struct pca9541 *data; 29162306a36Sopenharmony_ci int ret; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE_DATA)) 29462306a36Sopenharmony_ci return -ENODEV; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci /* 29762306a36Sopenharmony_ci * I2C accesses are unprotected here. 29862306a36Sopenharmony_ci * We have to lock the I2C segment before releasing the bus. 29962306a36Sopenharmony_ci */ 30062306a36Sopenharmony_ci i2c_lock_bus(adap, I2C_LOCK_SEGMENT); 30162306a36Sopenharmony_ci pca9541_release_bus(client); 30262306a36Sopenharmony_ci i2c_unlock_bus(adap, I2C_LOCK_SEGMENT); 30362306a36Sopenharmony_ci 30462306a36Sopenharmony_ci /* Create mux adapter */ 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci muxc = i2c_mux_alloc(adap, &client->dev, 1, sizeof(*data), 30762306a36Sopenharmony_ci I2C_MUX_ARBITRATOR, 30862306a36Sopenharmony_ci pca9541_select_chan, pca9541_release_chan); 30962306a36Sopenharmony_ci if (!muxc) 31062306a36Sopenharmony_ci return -ENOMEM; 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci data = i2c_mux_priv(muxc); 31362306a36Sopenharmony_ci data->client = client; 31462306a36Sopenharmony_ci 31562306a36Sopenharmony_ci i2c_set_clientdata(client, muxc); 31662306a36Sopenharmony_ci 31762306a36Sopenharmony_ci ret = i2c_mux_add_adapter(muxc, 0, 0, 0); 31862306a36Sopenharmony_ci if (ret) 31962306a36Sopenharmony_ci return ret; 32062306a36Sopenharmony_ci 32162306a36Sopenharmony_ci dev_info(&client->dev, "registered master selector for I2C %s\n", 32262306a36Sopenharmony_ci client->name); 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ci return 0; 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic void pca9541_remove(struct i2c_client *client) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci struct i2c_mux_core *muxc = i2c_get_clientdata(client); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci i2c_mux_del_adapters(muxc); 33262306a36Sopenharmony_ci} 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_cistatic struct i2c_driver pca9541_driver = { 33562306a36Sopenharmony_ci .driver = { 33662306a36Sopenharmony_ci .name = "pca9541", 33762306a36Sopenharmony_ci .of_match_table = of_match_ptr(pca9541_of_match), 33862306a36Sopenharmony_ci }, 33962306a36Sopenharmony_ci .probe = pca9541_probe, 34062306a36Sopenharmony_ci .remove = pca9541_remove, 34162306a36Sopenharmony_ci .id_table = pca9541_id, 34262306a36Sopenharmony_ci}; 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_cimodule_i2c_driver(pca9541_driver); 34562306a36Sopenharmony_ci 34662306a36Sopenharmony_ciMODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>"); 34762306a36Sopenharmony_ciMODULE_DESCRIPTION("PCA9541 I2C master selector driver"); 34862306a36Sopenharmony_ciMODULE_LICENSE("GPL v2"); 349