Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6

Conflicts:
	arch/sh/include/asm/Kbuild
	drivers/Makefile

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
This commit is contained in:
Paul Mundt
2010-08-16 13:32:24 +09:00
7954 changed files with 495097 additions and 558493 deletions

View File

@@ -47,6 +47,19 @@ config I2C_CHARDEV
This support is also available as a module. If so, the module
will be called i2c-dev.
config I2C_MUX
tristate "I2C bus multiplexing support"
depends on EXPERIMENTAL
help
Say Y here if you want the I2C core to support the ability to
handle multiplexed I2C bus topologies, by presenting each
multiplexed segment as a I2C adapter.
This support is also available as a module. If so, the module
will be called i2c-mux.
source drivers/i2c/muxes/Kconfig
config I2C_HELPER_AUTO
bool "Autoselect pertinent helper modules"
default y

View File

@@ -6,7 +6,8 @@ obj-$(CONFIG_I2C_BOARDINFO) += i2c-boardinfo.o
obj-$(CONFIG_I2C) += i2c-core.o
obj-$(CONFIG_I2C_SMBUS) += i2c-smbus.o
obj-$(CONFIG_I2C_CHARDEV) += i2c-dev.o
obj-y += algos/ busses/
obj-$(CONFIG_I2C_MUX) += i2c-mux.o
obj-y += algos/ busses/ muxes/
ifeq ($(CONFIG_I2C_DEBUG_CORE),y)
EXTRA_CFLAGS += -DDEBUG

View File

@@ -448,6 +448,13 @@ config I2C_NOMADIK
If you say yes to this option, support will be included for the
I2C interface from ST-Ericsson's Nomadik and Ux500 architectures.
config I2C_NUC900
tristate "NUC900 I2C Driver"
depends on ARCH_W90X900
help
Say Y here to include support for I2C controller in the
Winbond/Nuvoton NUC900 based System-on-Chip devices.
config I2C_OCORES
tristate "OpenCores I2C Controller"
depends on EXPERIMENTAL
@@ -496,8 +503,8 @@ config I2C_PMCMSP
will be called i2c-pmcmsp.
config I2C_PNX
tristate "I2C bus support for Philips PNX targets"
depends on ARCH_PNX4008
tristate "I2C bus support for Philips PNX and NXP LPC targets"
depends on ARCH_PNX4008 || ARCH_LPC32XX
help
This driver supports the Philips IP3204 I2C IP block master and/or
slave controller
@@ -521,12 +528,19 @@ config I2C_PXA_SLAVE
is necessary for systems where the PXA may be a target on the
I2C bus.
config HAVE_S3C2410_I2C
bool
help
This will include I2C support for Samsung SoCs. If you want to
include I2C support for any machine, kindly select this in the
respective Kconfig file.
config I2C_S3C2410
tristate "S3C2410 I2C Driver"
depends on ARCH_S3C2410 || ARCH_S3C64XX
depends on HAVE_S3C2410_I2C
help
Say Y here to include support for I2C controller in the
Samsung S3C2410 based System-on-Chip devices.
Samsung SoCs.
config I2C_S6000
tristate "S6000 I2C support"
@@ -549,7 +563,7 @@ config I2C_SH7760
config I2C_SH_MOBILE
tristate "SuperH Mobile I2C Controller"
depends on SUPERH
depends on SUPERH || ARCH_SHMOBILE
help
If you say yes to this option, support will be included for the
built-in I2C interface on the Renesas SH-Mobile processor.

View File

@@ -43,6 +43,7 @@ obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
obj-$(CONFIG_I2C_NUC900) += i2c-nuc900.o
obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o

View File

@@ -105,7 +105,7 @@ struct i2c_reg {
struct cpm_i2c {
char *base;
struct of_device *ofdev;
struct platform_device *ofdev;
struct i2c_adapter adap;
uint dp_addr;
int version; /* CPM1=1, CPM2=2 */
@@ -428,7 +428,7 @@ static const struct i2c_adapter cpm_ops = {
static int __devinit cpm_i2c_setup(struct cpm_i2c *cpm)
{
struct of_device *ofdev = cpm->ofdev;
struct platform_device *ofdev = cpm->ofdev;
const u32 *data;
int len, ret, i;
void __iomem *i2c_base;
@@ -634,7 +634,7 @@ static void cpm_i2c_shutdown(struct cpm_i2c *cpm)
cpm_muram_free(cpm->i2c_addr);
}
static int __devinit cpm_i2c_probe(struct of_device *ofdev,
static int __devinit cpm_i2c_probe(struct platform_device *ofdev,
const struct of_device_id *match)
{
int result, len;
@@ -652,6 +652,7 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
cpm->adap = cpm_ops;
i2c_set_adapdata(&cpm->adap, cpm);
cpm->adap.dev.parent = &ofdev->dev;
cpm->adap.dev.of_node = of_node_get(ofdev->dev.of_node);
result = cpm_i2c_setup(cpm);
if (result) {
@@ -676,11 +677,6 @@ static int __devinit cpm_i2c_probe(struct of_device *ofdev,
dev_dbg(&ofdev->dev, "hw routines for %s registered.\n",
cpm->adap.name);
/*
* register OF I2C devices
*/
of_register_i2c_devices(&cpm->adap, ofdev->dev.of_node);
return 0;
out_shut:
cpm_i2c_shutdown(cpm);
@@ -691,7 +687,7 @@ out_free:
return result;
}
static int __devexit cpm_i2c_remove(struct of_device *ofdev)
static int __devexit cpm_i2c_remove(struct platform_device *ofdev)
{
struct cpm_i2c *cpm = dev_get_drvdata(&ofdev->dev);

View File

@@ -36,14 +36,16 @@
#include <linux/platform_device.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/cpufreq.h>
#include <linux/gpio.h>
#include <mach/hardware.h>
#include <mach/i2c.h>
/* ----- global defines ----------------------------------------------- */
#define DAVINCI_I2C_TIMEOUT (1*HZ)
#define DAVINCI_I2C_MAX_TRIES 2
#define I2C_DAVINCI_INTR_ALL (DAVINCI_I2C_IMR_AAS | \
DAVINCI_I2C_IMR_SCD | \
DAVINCI_I2C_IMR_ARDY | \
@@ -72,37 +74,29 @@
#define DAVINCI_I2C_IVR_NACK 0x02
#define DAVINCI_I2C_IVR_AL 0x01
#define DAVINCI_I2C_STR_BB (1 << 12)
#define DAVINCI_I2C_STR_RSFULL (1 << 11)
#define DAVINCI_I2C_STR_SCD (1 << 5)
#define DAVINCI_I2C_STR_ARDY (1 << 2)
#define DAVINCI_I2C_STR_NACK (1 << 1)
#define DAVINCI_I2C_STR_AL (1 << 0)
#define DAVINCI_I2C_STR_BB BIT(12)
#define DAVINCI_I2C_STR_RSFULL BIT(11)
#define DAVINCI_I2C_STR_SCD BIT(5)
#define DAVINCI_I2C_STR_ARDY BIT(2)
#define DAVINCI_I2C_STR_NACK BIT(1)
#define DAVINCI_I2C_STR_AL BIT(0)
#define DAVINCI_I2C_MDR_NACK (1 << 15)
#define DAVINCI_I2C_MDR_STT (1 << 13)
#define DAVINCI_I2C_MDR_STP (1 << 11)
#define DAVINCI_I2C_MDR_MST (1 << 10)
#define DAVINCI_I2C_MDR_TRX (1 << 9)
#define DAVINCI_I2C_MDR_XA (1 << 8)
#define DAVINCI_I2C_MDR_RM (1 << 7)
#define DAVINCI_I2C_MDR_IRS (1 << 5)
#define DAVINCI_I2C_MDR_NACK BIT(15)
#define DAVINCI_I2C_MDR_STT BIT(13)
#define DAVINCI_I2C_MDR_STP BIT(11)
#define DAVINCI_I2C_MDR_MST BIT(10)
#define DAVINCI_I2C_MDR_TRX BIT(9)
#define DAVINCI_I2C_MDR_XA BIT(8)
#define DAVINCI_I2C_MDR_RM BIT(7)
#define DAVINCI_I2C_MDR_IRS BIT(5)
#define DAVINCI_I2C_IMR_AAS (1 << 6)
#define DAVINCI_I2C_IMR_SCD (1 << 5)
#define DAVINCI_I2C_IMR_XRDY (1 << 4)
#define DAVINCI_I2C_IMR_RRDY (1 << 3)
#define DAVINCI_I2C_IMR_ARDY (1 << 2)
#define DAVINCI_I2C_IMR_NACK (1 << 1)
#define DAVINCI_I2C_IMR_AL (1 << 0)
#define MOD_REG_BIT(val, mask, set) do { \
if (set) { \
val |= mask; \
} else { \
val &= ~mask; \
} \
} while (0)
#define DAVINCI_I2C_IMR_AAS BIT(6)
#define DAVINCI_I2C_IMR_SCD BIT(5)
#define DAVINCI_I2C_IMR_XRDY BIT(4)
#define DAVINCI_I2C_IMR_RRDY BIT(3)
#define DAVINCI_I2C_IMR_ARDY BIT(2)
#define DAVINCI_I2C_IMR_NACK BIT(1)
#define DAVINCI_I2C_IMR_AL BIT(0)
struct davinci_i2c_dev {
struct device *dev;
@@ -113,8 +107,13 @@ struct davinci_i2c_dev {
u8 *buf;
size_t buf_len;
int irq;
int stop;
u8 terminate;
struct i2c_adapter adapter;
#ifdef CONFIG_CPU_FREQ
struct completion xfr_complete;
struct notifier_block freq_transition;
#endif
};
/* default platform data to use if not supplied in the platform_device */
@@ -134,12 +133,59 @@ static inline u16 davinci_i2c_read_reg(struct davinci_i2c_dev *i2c_dev, int reg)
return __raw_readw(i2c_dev->base + reg);
}
/*
* This functions configures I2C and brings I2C out of reset.
* This function is called during I2C init function. This function
* also gets called if I2C encounters any errors.
/* Generate a pulse on the i2c clock pin. */
static void generic_i2c_clock_pulse(unsigned int scl_pin)
{
u16 i;
if (scl_pin) {
/* Send high and low on the SCL line */
for (i = 0; i < 9; i++) {
gpio_set_value(scl_pin, 0);
udelay(20);
gpio_set_value(scl_pin, 1);
udelay(20);
}
}
}
/* This routine does i2c bus recovery as specified in the
* i2c protocol Rev. 03 section 3.16 titled "Bus clear"
*/
static int i2c_davinci_init(struct davinci_i2c_dev *dev)
static void i2c_recover_bus(struct davinci_i2c_dev *dev)
{
u32 flag = 0;
struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
dev_err(dev->dev, "initiating i2c bus recovery\n");
/* Send NACK to the slave */
flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
flag |= DAVINCI_I2C_MDR_NACK;
/* write the data into mode register */
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
if (pdata)
generic_i2c_clock_pulse(pdata->scl_pin);
/* Send STOP */
flag = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
flag |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
}
static inline void davinci_i2c_reset_ctrl(struct davinci_i2c_dev *i2c_dev,
int val)
{
u16 w;
w = davinci_i2c_read_reg(i2c_dev, DAVINCI_I2C_MDR_REG);
if (!val) /* put I2C into reset */
w &= ~DAVINCI_I2C_MDR_IRS;
else /* take I2C out of reset */
w |= DAVINCI_I2C_MDR_IRS;
davinci_i2c_write_reg(i2c_dev, DAVINCI_I2C_MDR_REG, w);
}
static void i2c_davinci_calc_clk_dividers(struct davinci_i2c_dev *dev)
{
struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
u16 psc;
@@ -148,15 +194,6 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
u32 clkh;
u32 clkl;
u32 input_clock = clk_get_rate(dev->clk);
u16 w;
if (!pdata)
pdata = &davinci_i2c_platform_data_default;
/* put I2C into reset */
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 0);
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
/* NOTE: I2C Clock divider programming info
* As per I2C specs the following formulas provide prescaler
@@ -188,12 +225,32 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKH_REG, clkh);
davinci_i2c_write_reg(dev, DAVINCI_I2C_CLKL_REG, clkl);
dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
}
/*
* This function configures I2C and brings I2C out of reset.
* This function is called during I2C init function. This function
* also gets called if I2C encounters any errors.
*/
static int i2c_davinci_init(struct davinci_i2c_dev *dev)
{
struct davinci_i2c_platform_data *pdata = dev->dev->platform_data;
if (!pdata)
pdata = &davinci_i2c_platform_data_default;
/* put I2C into reset */
davinci_i2c_reset_ctrl(dev, 0);
/* compute clock dividers */
i2c_davinci_calc_clk_dividers(dev);
/* Respond at reserved "SMBus Host" slave address" (and zero);
* we seem to have no option to not respond...
*/
davinci_i2c_write_reg(dev, DAVINCI_I2C_OAR_REG, 0x08);
dev_dbg(dev->dev, "input_clock = %d, CLK = %d\n", input_clock, clk);
dev_dbg(dev->dev, "PSC = %d\n",
davinci_i2c_read_reg(dev, DAVINCI_I2C_PSC_REG));
dev_dbg(dev->dev, "CLKL = %d\n",
@@ -204,9 +261,7 @@ static int i2c_davinci_init(struct davinci_i2c_dev *dev)
pdata->bus_freq, pdata->bus_delay);
/* Take the I2C module out of reset: */
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
MOD_REG_BIT(w, DAVINCI_I2C_MDR_IRS, 1);
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
davinci_i2c_reset_ctrl(dev, 1);
/* Enable interrupts */
davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, I2C_DAVINCI_INTR_ALL);
@@ -221,14 +276,22 @@ static int i2c_davinci_wait_bus_not_busy(struct davinci_i2c_dev *dev,
char allow_sleep)
{
unsigned long timeout;
static u16 to_cnt;
timeout = jiffies + dev->adapter.timeout;
while (davinci_i2c_read_reg(dev, DAVINCI_I2C_STR_REG)
& DAVINCI_I2C_STR_BB) {
if (time_after(jiffies, timeout)) {
dev_warn(dev->dev,
"timeout waiting for bus ready\n");
return -ETIMEDOUT;
if (to_cnt <= DAVINCI_I2C_MAX_TRIES) {
if (time_after(jiffies, timeout)) {
dev_warn(dev->dev,
"timeout waiting for bus ready\n");
to_cnt++;
return -ETIMEDOUT;
} else {
to_cnt = 0;
i2c_recover_bus(dev);
i2c_davinci_init(dev);
}
}
if (allow_sleep)
schedule_timeout(1);
@@ -250,9 +313,6 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
u16 w;
int r;
if (msg->len == 0)
return -EINVAL;
if (!pdata)
pdata = &davinci_i2c_platform_data_default;
/* Introduce a delay, required for some boards (e.g Davinci EVM) */
@@ -264,6 +324,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
dev->buf = msg->buf;
dev->buf_len = msg->len;
dev->stop = stop;
davinci_i2c_write_reg(dev, DAVINCI_I2C_CNT_REG, dev->buf_len);
@@ -281,23 +342,40 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
flag |= DAVINCI_I2C_MDR_TRX;
if (stop)
flag |= DAVINCI_I2C_MDR_STP;
if (msg->len == 0) {
flag |= DAVINCI_I2C_MDR_RM;
flag &= ~DAVINCI_I2C_MDR_STP;
}
/* Enable receive or transmit interrupts */
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_IMR_REG);
if (msg->flags & I2C_M_RD)
MOD_REG_BIT(w, DAVINCI_I2C_IMR_RRDY, 1);
w |= DAVINCI_I2C_IMR_RRDY;
else
MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 1);
w |= DAVINCI_I2C_IMR_XRDY;
davinci_i2c_write_reg(dev, DAVINCI_I2C_IMR_REG, w);
dev->terminate = 0;
/* write the data into mode register */
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, flag);
/*
* First byte should be set here, not after interrupt,
* because transmit-data-ready interrupt can come before
* NACK-interrupt during sending of previous message and
* ICDXR may have wrong data
*/
if ((!(msg->flags & I2C_M_RD)) && dev->buf_len) {
davinci_i2c_write_reg(dev, DAVINCI_I2C_DXR_REG, *dev->buf++);
dev->buf_len--;
}
r = wait_for_completion_interruptible_timeout(&dev->cmd_complete,
dev->adapter.timeout);
if (r == 0) {
dev_err(dev->dev, "controller timed out\n");
i2c_recover_bus(dev);
i2c_davinci_init(dev);
dev->buf_len = 0;
return -ETIMEDOUT;
@@ -334,7 +412,7 @@ i2c_davinci_xfer_msg(struct i2c_adapter *adap, struct i2c_msg *msg, int stop)
return msg->len;
if (stop) {
w = davinci_i2c_read_reg(dev, DAVINCI_I2C_MDR_REG);
MOD_REG_BIT(w, DAVINCI_I2C_MDR_STP, 1);
w |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, w);
}
return -EREMOTEIO;
@@ -367,12 +445,17 @@ i2c_davinci_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num)
if (ret < 0)
return ret;
}
#ifdef CONFIG_CPU_FREQ
complete(&dev->xfr_complete);
#endif
return num;
}
static u32 i2c_davinci_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK);
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL;
}
static void terminate_read(struct davinci_i2c_dev *dev)
@@ -431,6 +514,14 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
case DAVINCI_I2C_IVR_ARDY:
davinci_i2c_write_reg(dev,
DAVINCI_I2C_STR_REG, DAVINCI_I2C_STR_ARDY);
if (((dev->buf_len == 0) && (dev->stop != 0)) ||
(dev->cmd_err & DAVINCI_I2C_STR_NACK)) {
w = davinci_i2c_read_reg(dev,
DAVINCI_I2C_MDR_REG);
w |= DAVINCI_I2C_MDR_STP;
davinci_i2c_write_reg(dev,
DAVINCI_I2C_MDR_REG, w);
}
complete(&dev->cmd_complete);
break;
@@ -462,7 +553,7 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
w = davinci_i2c_read_reg(dev,
DAVINCI_I2C_IMR_REG);
MOD_REG_BIT(w, DAVINCI_I2C_IMR_XRDY, 0);
w &= ~DAVINCI_I2C_IMR_XRDY;
davinci_i2c_write_reg(dev,
DAVINCI_I2C_IMR_REG,
w);
@@ -491,6 +582,48 @@ static irqreturn_t i2c_davinci_isr(int this_irq, void *dev_id)
return count ? IRQ_HANDLED : IRQ_NONE;
}
#ifdef CONFIG_CPU_FREQ
static int i2c_davinci_cpufreq_transition(struct notifier_block *nb,
unsigned long val, void *data)
{
struct davinci_i2c_dev *dev;
dev = container_of(nb, struct davinci_i2c_dev, freq_transition);
if (val == CPUFREQ_PRECHANGE) {
wait_for_completion(&dev->xfr_complete);
davinci_i2c_reset_ctrl(dev, 0);
} else if (val == CPUFREQ_POSTCHANGE) {
i2c_davinci_calc_clk_dividers(dev);
davinci_i2c_reset_ctrl(dev, 1);
}
return 0;
}
static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
{
dev->freq_transition.notifier_call = i2c_davinci_cpufreq_transition;
return cpufreq_register_notifier(&dev->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
}
static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
{
cpufreq_unregister_notifier(&dev->freq_transition,
CPUFREQ_TRANSITION_NOTIFIER);
}
#else
static inline int i2c_davinci_cpufreq_register(struct davinci_i2c_dev *dev)
{
return 0;
}
static inline void i2c_davinci_cpufreq_deregister(struct davinci_i2c_dev *dev)
{
}
#endif
static struct i2c_algorithm i2c_davinci_algo = {
.master_xfer = i2c_davinci_xfer,
.functionality = i2c_davinci_func,
@@ -530,6 +663,9 @@ static int davinci_i2c_probe(struct platform_device *pdev)
}
init_completion(&dev->cmd_complete);
#ifdef CONFIG_CPU_FREQ
init_completion(&dev->xfr_complete);
#endif
dev->dev = get_device(&pdev->dev);
dev->irq = irq->start;
platform_set_drvdata(pdev, dev);
@@ -541,7 +677,12 @@ static int davinci_i2c_probe(struct platform_device *pdev)
}
clk_enable(dev->clk);
dev->base = (void __iomem *)IO_ADDRESS(mem->start);
dev->base = ioremap(mem->start, resource_size(mem));
if (!dev->base) {
r = -EBUSY;
goto err_mem_ioremap;
}
i2c_davinci_init(dev);
r = request_irq(dev->irq, i2c_davinci_isr, 0, pdev->name, dev);
@@ -550,6 +691,12 @@ static int davinci_i2c_probe(struct platform_device *pdev)
goto err_unuse_clocks;
}
r = i2c_davinci_cpufreq_register(dev);
if (r) {
dev_err(&pdev->dev, "failed to register cpufreq\n");
goto err_free_irq;
}
adap = &dev->adapter;
i2c_set_adapdata(adap, dev);
adap->owner = THIS_MODULE;
@@ -571,6 +718,8 @@ static int davinci_i2c_probe(struct platform_device *pdev)
err_free_irq:
free_irq(dev->irq, dev);
err_unuse_clocks:
iounmap(dev->base);
err_mem_ioremap:
clk_disable(dev->clk);
clk_put(dev->clk);
dev->clk = NULL;
@@ -589,6 +738,8 @@ static int davinci_i2c_remove(struct platform_device *pdev)
struct davinci_i2c_dev *dev = platform_get_drvdata(pdev);
struct resource *mem;
i2c_davinci_cpufreq_deregister(dev);
platform_set_drvdata(pdev, NULL);
i2c_del_adapter(&dev->adapter);
put_device(&pdev->dev);
@@ -599,6 +750,7 @@ static int davinci_i2c_remove(struct platform_device *pdev)
davinci_i2c_write_reg(dev, DAVINCI_I2C_MDR_REG, 0);
free_irq(IRQ_I2C, dev);
iounmap(dev->base);
kfree(dev);
mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -606,6 +758,41 @@ static int davinci_i2c_remove(struct platform_device *pdev)
return 0;
}
#ifdef CONFIG_PM
static int davinci_i2c_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
/* put I2C into reset */
davinci_i2c_reset_ctrl(i2c_dev, 0);
clk_disable(i2c_dev->clk);
return 0;
}
static int davinci_i2c_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct davinci_i2c_dev *i2c_dev = platform_get_drvdata(pdev);
clk_enable(i2c_dev->clk);
/* take I2C out of reset */
davinci_i2c_reset_ctrl(i2c_dev, 1);
return 0;
}
static const struct dev_pm_ops davinci_i2c_pm = {
.suspend = davinci_i2c_suspend,
.resume = davinci_i2c_resume,
};
#define davinci_i2c_pm_ops (&davinci_i2c_pm)
#else
#define davinci_i2c_pm_ops NULL
#endif
/* work with hotplug and coldplug */
MODULE_ALIAS("platform:i2c_davinci");
@@ -615,6 +802,7 @@ static struct platform_driver davinci_i2c_driver = {
.driver = {
.name = "i2c_davinci",
.owner = THIS_MODULE,
.pm = davinci_i2c_pm_ops,
},
};

View File

@@ -661,7 +661,7 @@ static inline u8 iic_clckdiv(unsigned int opb)
return (u8)((opb + 9) / 10 - 1);
}
static int __devinit iic_request_irq(struct of_device *ofdev,
static int __devinit iic_request_irq(struct platform_device *ofdev,
struct ibm_iic_private *dev)
{
struct device_node *np = ofdev->dev.of_node;
@@ -692,7 +692,7 @@ static int __devinit iic_request_irq(struct of_device *ofdev,
/*
* Register single IIC interface
*/
static int __devinit iic_probe(struct of_device *ofdev,
static int __devinit iic_probe(struct platform_device *ofdev,
const struct of_device_id *match)
{
struct device_node *np = ofdev->dev.of_node;
@@ -745,6 +745,7 @@ static int __devinit iic_probe(struct of_device *ofdev,
/* Register it with i2c layer */
adap = &dev->adap;
adap->dev.parent = &ofdev->dev;
adap->dev.of_node = of_node_get(np);
strlcpy(adap->name, "IBM IIC", sizeof(adap->name));
i2c_set_adapdata(adap, dev);
adap->class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
@@ -760,9 +761,6 @@ static int __devinit iic_probe(struct of_device *ofdev,
dev_info(&ofdev->dev, "using %s mode\n",
dev->fast_mode ? "fast (400 kHz)" : "standard (100 kHz)");
/* Now register all the child nodes */
of_register_i2c_devices(adap, np);
return 0;
error_cleanup:
@@ -782,7 +780,7 @@ error_cleanup:
/*
* Cleanup initialized IIC interface
*/
static int __devexit iic_remove(struct of_device *ofdev)
static int __devexit iic_remove(struct platform_device *ofdev)
{
struct ibm_iic_private *dev = dev_get_drvdata(&ofdev->dev);

View File

@@ -63,6 +63,7 @@ struct mpc_i2c {
wait_queue_head_t queue;
struct i2c_adapter adap;
int irq;
u32 real_clk;
};
struct mpc_i2c_divider {
@@ -96,20 +97,23 @@ static irqreturn_t mpc_i2c_isr(int irq, void *dev_id)
/* Sometimes 9th clock pulse isn't generated, and slave doesn't release
* the bus, because it wants to send ACK.
* Following sequence of enabling/disabling and sending start/stop generates
* the pulse, so it's all OK.
* the 9 pulses, so it's all OK.
*/
static void mpc_i2c_fixup(struct mpc_i2c *i2c)
{
writeccr(i2c, 0);
udelay(30);
writeccr(i2c, CCR_MEN);
udelay(30);
writeccr(i2c, CCR_MSTA | CCR_MTX);
udelay(30);
writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
udelay(30);
writeccr(i2c, CCR_MEN);
udelay(30);
int k;
u32 delay_val = 1000000 / i2c->real_clk + 1;
if (delay_val < 2)
delay_val = 2;
for (k = 9; k; k--) {
writeccr(i2c, 0);
writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN);
udelay(delay_val);
writeccr(i2c, CCR_MEN);
udelay(delay_val << 1);
}
}
static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
@@ -190,15 +194,18 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
};
static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
int prescaler)
int prescaler, u32 *real_clk)
{
const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR);
u32 divider;
int i;
if (clock == MPC_I2C_CLOCK_LEGACY)
if (clock == MPC_I2C_CLOCK_LEGACY) {
/* see below - default fdr = 0x3f -> div = 2048 */
*real_clk = mpc5xxx_get_bus_frequency(node) / 2048;
return -EINVAL;
}
/* Determine divider value */
divider = mpc5xxx_get_bus_frequency(node) / clock;
@@ -216,7 +223,8 @@ static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
break;
}
return div ? (int)div->fdr : -EINVAL;
*real_clk = mpc5xxx_get_bus_frequency(node) / div->divider;
return (int)div->fdr;
}
static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
@@ -231,13 +239,14 @@ static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
return;
}
ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler, &i2c->real_clk);
fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
if (ret >= 0)
dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
dev_info(i2c->dev, "clock %u Hz (fdr=%d)\n", i2c->real_clk,
fdr);
}
#else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
@@ -334,14 +343,17 @@ static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
}
static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
u32 prescaler)
u32 prescaler, u32 *real_clk)
{
const struct mpc_i2c_divider *div = NULL;
u32 divider;
int i;
if (clock == MPC_I2C_CLOCK_LEGACY)
if (clock == MPC_I2C_CLOCK_LEGACY) {
/* see below - default fdr = 0x1031 -> div = 16 * 3072 */
*real_clk = fsl_get_sys_freq() / prescaler / (16 * 3072);
return -EINVAL;
}
/* Determine proper divider value */
if (of_device_is_compatible(node, "fsl,mpc8544-i2c"))
@@ -364,6 +376,7 @@ static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
break;
}
*real_clk = fsl_get_sys_freq() / prescaler / div->divider;
return div ? (int)div->fdr : -EINVAL;
}
@@ -380,7 +393,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
return;
}
ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler, &i2c->real_clk);
fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
writeb(fdr & 0xff, i2c->base + MPC_I2C_FDR);
@@ -388,7 +401,7 @@ static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
if (ret >= 0)
dev_info(i2c->dev, "clock %d Hz (dfsrr=%d fdr=%d)\n",
clock, fdr >> 8, fdr & 0xff);
i2c->real_clk, fdr >> 8, fdr & 0xff);
}
#else /* !CONFIG_FSL_SOC */
@@ -500,10 +513,14 @@ static int mpc_xfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
return -EINTR;
}
if (time_after(jiffies, orig_jiffies + HZ)) {
u8 status = readb(i2c->base + MPC_I2C_SR);
dev_dbg(i2c->dev, "timeout\n");
if (readb(i2c->base + MPC_I2C_SR) ==
(CSR_MCF | CSR_MBB | CSR_RXAK))
if ((status & (CSR_MCF | CSR_MBB | CSR_RXAK)) != 0) {
writeb(status & ~CSR_MAL,
i2c->base + MPC_I2C_SR);
mpc_i2c_fixup(i2c);
}
return -EIO;
}
schedule();
@@ -543,7 +560,7 @@ static struct i2c_adapter mpc_ops = {
.timeout = HZ,
};
static int __devinit fsl_i2c_probe(struct of_device *op,
static int __devinit fsl_i2c_probe(struct platform_device *op,
const struct of_device_id *match)
{
struct mpc_i2c *i2c;
@@ -595,18 +612,26 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
mpc_i2c_setup_8xxx(op->dev.of_node, i2c, clock, 0);
}
prop = of_get_property(op->dev.of_node, "fsl,timeout", &plen);
if (prop && plen == sizeof(u32)) {
mpc_ops.timeout = *prop * HZ / 1000000;
if (mpc_ops.timeout < 5)
mpc_ops.timeout = 5;
}
dev_info(i2c->dev, "timeout %u us\n", mpc_ops.timeout * 1000000 / HZ);
dev_set_drvdata(&op->dev, i2c);
i2c->adap = mpc_ops;
i2c_set_adapdata(&i2c->adap, i2c);
i2c->adap.dev.parent = &op->dev;
i2c->adap.dev.of_node = of_node_get(op->dev.of_node);
result = i2c_add_adapter(&i2c->adap);
if (result < 0) {
dev_err(i2c->dev, "failed to add adapter\n");
goto fail_add;
}
of_register_i2c_devices(&i2c->adap, op->dev.of_node);
return result;
@@ -621,7 +646,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
return result;
};
static int __devexit fsl_i2c_remove(struct of_device *op)
static int __devexit fsl_i2c_remove(struct platform_device *op)
{
struct mpc_i2c *i2c = dev_get_drvdata(&op->dev);

View File

@@ -0,0 +1,709 @@
/*
* linux/drivers/i2c/busses/i2c-nuc900.c
*
* Copyright (c) 2010 Nuvoton technology corporation.
*
* This driver based on S3C2410 I2C driver of Ben Dooks <ben-Y5A6D6n0/KfQXOPxS62xeg@public.gmane.org>.
* Written by Wan ZongShun <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation;version 2 of the License.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/i2c-id.h>
#include <linux/init.h>
#include <linux/time.h>
#include <linux/interrupt.h>
#include <linux/delay.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <mach/mfp.h>
#include <mach/i2c.h>
/* nuc900 i2c registers offset */
#define CSR 0x00
#define DIVIDER 0x04
#define CMDR 0x08
#define SWR 0x0C
#define RXR 0x10
#define TXR 0x14
/* nuc900 i2c CSR register bits */
#define IRQEN 0x003
#define I2CBUSY 0x400
#define I2CSTART 0x018
#define IRQFLAG 0x004
#define ARBIT_LOST 0x200
#define SLAVE_ACK 0x800
/* nuc900 i2c CMDR register bits */
#define I2C_CMD_START 0x10
#define I2C_CMD_STOP 0x08
#define I2C_CMD_READ 0x04
#define I2C_CMD_WRITE 0x02
#define I2C_CMD_NACK 0x01
/* i2c controller state */
enum nuc900_i2c_state {
STATE_IDLE,
STATE_START,
STATE_READ,
STATE_WRITE,
STATE_STOP
};
/* i2c controller private data */
struct nuc900_i2c {
spinlock_t lock;
wait_queue_head_t wait;
struct i2c_msg *msg;
unsigned int msg_num;
unsigned int msg_idx;
unsigned int msg_ptr;
unsigned int irq;
enum nuc900_i2c_state state;
void __iomem *regs;
struct clk *clk;
struct device *dev;
struct resource *ioarea;
struct i2c_adapter adap;
};
/* nuc900_i2c_master_complete
*
* complete the message and wake up the caller, using the given return code,
* or zero to mean ok.
*/
static inline void nuc900_i2c_master_complete(struct nuc900_i2c *i2c, int ret)
{
dev_dbg(i2c->dev, "master_complete %d\n", ret);
i2c->msg_ptr = 0;
i2c->msg = NULL;
i2c->msg_idx++;
i2c->msg_num = 0;
if (ret)
i2c->msg_idx = ret;
wake_up(&i2c->wait);
}
/* irq enable/disable functions */
static inline void nuc900_i2c_disable_irq(struct nuc900_i2c *i2c)
{
unsigned long tmp;
tmp = readl(i2c->regs + CSR);
writel(tmp & ~IRQEN, i2c->regs + CSR);
}
static inline void nuc900_i2c_enable_irq(struct nuc900_i2c *i2c)
{
unsigned long tmp;
tmp = readl(i2c->regs + CSR);
writel(tmp | IRQEN, i2c->regs + CSR);
}
/* nuc900_i2c_message_start
*
* put the start of a message onto the bus
*/
static void nuc900_i2c_message_start(struct nuc900_i2c *i2c,
struct i2c_msg *msg)
{
unsigned int addr = (msg->addr & 0x7f) << 1;
if (msg->flags & I2C_M_RD)
addr |= 0x1;
writel(addr & 0xff, i2c->regs + TXR);
writel(I2C_CMD_START | I2C_CMD_WRITE, i2c->regs + CMDR);
}
static inline void nuc900_i2c_stop(struct nuc900_i2c *i2c, int ret)
{
dev_dbg(i2c->dev, "STOP\n");
/* stop the transfer */
i2c->state = STATE_STOP;
writel(I2C_CMD_STOP, i2c->regs + CMDR);
nuc900_i2c_master_complete(i2c, ret);
nuc900_i2c_disable_irq(i2c);
}
/* helper functions to determine the current state in the set of
* messages we are sending
*/
/* is_lastmsg()
*
* returns TRUE if the current message is the last in the set
*/
static inline int is_lastmsg(struct nuc900_i2c *i2c)
{
return i2c->msg_idx >= (i2c->msg_num - 1);
}
/* is_msglast
*
* returns TRUE if we this is the last byte in the current message
*/
static inline int is_msglast(struct nuc900_i2c *i2c)
{
return i2c->msg_ptr == i2c->msg->len-1;
}
/* is_msgend
*
* returns TRUE if we reached the end of the current message
*/
static inline int is_msgend(struct nuc900_i2c *i2c)
{
return i2c->msg_ptr >= i2c->msg->len;
}
/* i2c_nuc900_irq_nextbyte
*
* process an interrupt and work out what to do
*/
static void i2c_nuc900_irq_nextbyte(struct nuc900_i2c *i2c,
unsigned long iicstat)
{
unsigned char byte;
switch (i2c->state) {
case STATE_IDLE:
dev_err(i2c->dev, "%s: called in STATE_IDLE\n", __func__);
break;
case STATE_STOP:
dev_err(i2c->dev, "%s: called in STATE_STOP\n", __func__);
nuc900_i2c_disable_irq(i2c);
break;
case STATE_START:
/* last thing we did was send a start condition on the
* bus, or started a new i2c message
*/
if (iicstat & SLAVE_ACK &&
!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
/* ack was not received... */
dev_dbg(i2c->dev, "ack was not received\n");
nuc900_i2c_stop(i2c, -ENXIO);
break;
}
if (i2c->msg->flags & I2C_M_RD)
i2c->state = STATE_READ;
else
i2c->state = STATE_WRITE;
/* terminate the transfer if there is nothing to do
* as this is used by the i2c probe to find devices.
*/
if (is_lastmsg(i2c) && i2c->msg->len == 0) {
nuc900_i2c_stop(i2c, 0);
break;
}
if (i2c->state == STATE_READ)
goto prepare_read;
/* fall through to the write state, as we will need to
* send a byte as well
*/
case STATE_WRITE:
/* we are writing data to the device... check for the
* end of the message, and if so, work out what to do
*/
if (!(i2c->msg->flags & I2C_M_IGNORE_NAK)) {
if (iicstat & SLAVE_ACK) {
dev_dbg(i2c->dev, "WRITE: No Ack\n");
nuc900_i2c_stop(i2c, -ECONNREFUSED);
break;
}
}
retry_write:
if (!is_msgend(i2c)) {
byte = i2c->msg->buf[i2c->msg_ptr++];
writeb(byte, i2c->regs + TXR);
writel(I2C_CMD_WRITE, i2c->regs + CMDR);
} else if (!is_lastmsg(i2c)) {
/* we need to go to the next i2c message */
dev_dbg(i2c->dev, "WRITE: Next Message\n");
i2c->msg_ptr = 0;
i2c->msg_idx++;
i2c->msg++;
/* check to see if we need to do another message */
if (i2c->msg->flags & I2C_M_NOSTART) {
if (i2c->msg->flags & I2C_M_RD) {
/* cannot do this, the controller
* forces us to send a new START
* when we change direction
*/
nuc900_i2c_stop(i2c, -EINVAL);
}
goto retry_write;
} else {
/* send the new start */
nuc900_i2c_message_start(i2c, i2c->msg);
i2c->state = STATE_START;
}
} else {
/* send stop */
nuc900_i2c_stop(i2c, 0);
}
break;
case STATE_READ:
/* we have a byte of data in the data register, do
* something with it, and then work out wether we are
* going to do any more read/write
*/
byte = readb(i2c->regs + RXR);
i2c->msg->buf[i2c->msg_ptr++] = byte;
prepare_read:
if (is_msglast(i2c)) {
/* last byte of buffer */
if (is_lastmsg(i2c))
writel(I2C_CMD_READ | I2C_CMD_NACK,
i2c->regs + CMDR);
} else if (is_msgend(i2c)) {
/* ok, we've read the entire buffer, see if there
* is anything else we need to do
*/
if (is_lastmsg(i2c)) {
/* last message, send stop and complete */
dev_dbg(i2c->dev, "READ: Send Stop\n");
nuc900_i2c_stop(i2c, 0);
} else {
/* go to the next transfer */
dev_dbg(i2c->dev, "READ: Next Transfer\n");
i2c->msg_ptr = 0;
i2c->msg_idx++;
i2c->msg++;
writel(I2C_CMD_READ, i2c->regs + CMDR);
}
} else {
writel(I2C_CMD_READ, i2c->regs + CMDR);
}
break;
}
}
/* nuc900_i2c_irq
*
* top level IRQ servicing routine
*/
static irqreturn_t nuc900_i2c_irq(int irqno, void *dev_id)
{
struct nuc900_i2c *i2c = dev_id;
unsigned long status;
status = readl(i2c->regs + CSR);
writel(status | IRQFLAG, i2c->regs + CSR);
if (status & ARBIT_LOST) {
/* deal with arbitration loss */
dev_err(i2c->dev, "deal with arbitration loss\n");
goto out;
}
if (i2c->state == STATE_IDLE) {
dev_dbg(i2c->dev, "IRQ: error i2c->state == IDLE\n");
goto out;
}
/* pretty much this leaves us with the fact that we've
* transmitted or received whatever byte we last sent
*/
i2c_nuc900_irq_nextbyte(i2c, status);
out:
return IRQ_HANDLED;
}
/* nuc900_i2c_set_master
*
* get the i2c bus for a master transaction
*/
static int nuc900_i2c_set_master(struct nuc900_i2c *i2c)
{
int timeout = 400;
while (timeout-- > 0) {
if (((readl(i2c->regs + SWR) & I2CSTART) == I2CSTART) &&
((readl(i2c->regs + CSR) & I2CBUSY) == 0)) {
return 0;
}
msleep(1);
}
return -ETIMEDOUT;
}
/* nuc900_i2c_doxfer
*
* this starts an i2c transfer
*/
static int nuc900_i2c_doxfer(struct nuc900_i2c *i2c,
struct i2c_msg *msgs, int num)
{
unsigned long iicstat, timeout;
int spins = 20;
int ret;
ret = nuc900_i2c_set_master(i2c);
if (ret != 0) {
dev_err(i2c->dev, "cannot get bus (error %d)\n", ret);
ret = -EAGAIN;
goto out;
}
spin_lock_irq(&i2c->lock);
i2c->msg = msgs;
i2c->msg_num = num;
i2c->msg_ptr = 0;
i2c->msg_idx = 0;
i2c->state = STATE_START;
nuc900_i2c_message_start(i2c, msgs);
spin_unlock_irq(&i2c->lock);
timeout = wait_event_timeout(i2c->wait, i2c->msg_num == 0, HZ * 5);
ret = i2c->msg_idx;
/* having these next two as dev_err() makes life very
* noisy when doing an i2cdetect
*/
if (timeout == 0)
dev_dbg(i2c->dev, "timeout\n");
else if (ret != num)
dev_dbg(i2c->dev, "incomplete xfer (%d)\n", ret);
/* ensure the stop has been through the bus */
dev_dbg(i2c->dev, "waiting for bus idle\n");
/* first, try busy waiting briefly */
do {
iicstat = readl(i2c->regs + CSR);
} while ((iicstat & I2CBUSY) && --spins);
/* if that timed out sleep */
if (!spins) {
msleep(1);
iicstat = readl(i2c->regs + CSR);
}
if (iicstat & I2CBUSY)
dev_warn(i2c->dev, "timeout waiting for bus idle\n");
out:
return ret;
}
/* nuc900_i2c_xfer
*
* first port of call from the i2c bus code when an message needs
* transferring across the i2c bus.
*/
static int nuc900_i2c_xfer(struct i2c_adapter *adap,
struct i2c_msg *msgs, int num)
{
struct nuc900_i2c *i2c = (struct nuc900_i2c *)adap->algo_data;
int retry;
int ret;
nuc900_i2c_enable_irq(i2c);
for (retry = 0; retry < adap->retries; retry++) {
ret = nuc900_i2c_doxfer(i2c, msgs, num);
if (ret != -EAGAIN)
return ret;
dev_dbg(i2c->dev, "Retrying transmission (%d)\n", retry);
udelay(100);
}
return -EREMOTEIO;
}
/* declare our i2c functionality */
static u32 nuc900_i2c_func(struct i2c_adapter *adap)
{
return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL | I2C_FUNC_PROTOCOL_MANGLING;
}
/* i2c bus registration info */
static const struct i2c_algorithm nuc900_i2c_algorithm = {
.master_xfer = nuc900_i2c_xfer,
.functionality = nuc900_i2c_func,
};
/* nuc900_i2c_probe
*
* called by the bus driver when a suitable device is found
*/
static int __devinit nuc900_i2c_probe(struct platform_device *pdev)
{
struct nuc900_i2c *i2c;
struct nuc900_platform_i2c *pdata;
struct resource *res;
int ret;
pdata = pdev->dev.platform_data;
if (!pdata) {
dev_err(&pdev->dev, "no platform data\n");
return -EINVAL;
}
i2c = kzalloc(sizeof(struct nuc900_i2c), GFP_KERNEL);
if (!i2c) {
dev_err(&pdev->dev, "no memory for state\n");
return -ENOMEM;
}
strlcpy(i2c->adap.name, "nuc900-i2c0", sizeof(i2c->adap.name));
i2c->adap.owner = THIS_MODULE;
i2c->adap.algo = &nuc900_i2c_algorithm;
i2c->adap.retries = 2;
i2c->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD;
spin_lock_init(&i2c->lock);
init_waitqueue_head(&i2c->wait);
/* find the clock and enable it */
i2c->dev = &pdev->dev;
i2c->clk = clk_get(&pdev->dev, NULL);
if (IS_ERR(i2c->clk)) {
dev_err(&pdev->dev, "cannot get clock\n");
ret = -ENOENT;
goto err_noclk;
}
dev_dbg(&pdev->dev, "clock source %p\n", i2c->clk);
clk_enable(i2c->clk);
/* map the registers */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (res == NULL) {
dev_err(&pdev->dev, "cannot find IO resource\n");
ret = -ENOENT;
goto err_clk;
}
i2c->ioarea = request_mem_region(res->start, resource_size(res),
pdev->name);
if (i2c->ioarea == NULL) {
dev_err(&pdev->dev, "cannot request IO\n");
ret = -ENXIO;
goto err_clk;
}
i2c->regs = ioremap(res->start, resource_size(res));
if (i2c->regs == NULL) {
dev_err(&pdev->dev, "cannot map IO\n");
ret = -ENXIO;
goto err_ioarea;
}
dev_dbg(&pdev->dev, "registers %p (%p, %p)\n",
i2c->regs, i2c->ioarea, res);
/* setup info block for the i2c core */
i2c->adap.algo_data = i2c;
i2c->adap.dev.parent = &pdev->dev;
mfp_set_groupg(&pdev->dev);
clk_get_rate(i2c->clk);
ret = (i2c->clk.apbfreq)/(pdata->bus_freq * 5) - 1;
writel(ret & 0xffff, i2c->regs + DIVIDER);
/* find the IRQ for this unit (note, this relies on the init call to
* ensure no current IRQs pending
*/
i2c->irq = ret = platform_get_irq(pdev, 0);
if (ret <= 0) {
dev_err(&pdev->dev, "cannot find IRQ\n");
goto err_iomap;
}
ret = request_irq(i2c->irq, nuc900_i2c_irq, IRQF_DISABLED | IRQF_SHARED,
dev_name(&pdev->dev), i2c);
if (ret != 0) {
dev_err(&pdev->dev, "cannot claim IRQ %d\n", i2c->irq);
goto err_iomap;
}
/* Note, previous versions of the driver used i2c_add_adapter()
* to add the bus at any number. We now pass the bus number via
* the platform data, so if unset it will now default to always
* being bus 0.
*/
i2c->adap.nr = pdata->bus_num;
ret = i2c_add_numbered_adapter(&i2c->adap);
if (ret < 0) {
dev_err(&pdev->dev, "failed to add bus to i2c core\n");
goto err_irq;
}
platform_set_drvdata(pdev, i2c);
dev_info(&pdev->dev, "%s: NUC900 I2C adapter\n",
dev_name(&i2c->adap.dev));
return 0;
err_irq:
free_irq(i2c->irq, i2c);
err_iomap:
iounmap(i2c->regs);
err_ioarea:
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
err_clk:
clk_disable(i2c->clk);
clk_put(i2c->clk);
err_noclk:
kfree(i2c);
return ret;
}
/* nuc900_i2c_remove
*
* called when device is removed from the bus
*/
static int __devexit nuc900_i2c_remove(struct platform_device *pdev)
{
struct nuc900_i2c *i2c = platform_get_drvdata(pdev);
i2c_del_adapter(&i2c->adap);
free_irq(i2c->irq, i2c);
clk_disable(i2c->clk);
clk_put(i2c->clk);
iounmap(i2c->regs);
release_resource(i2c->ioarea);
kfree(i2c->ioarea);
kfree(i2c);
return 0;
}
static struct platform_driver nuc900_i2c_driver = {
.probe = nuc900_i2c_probe,
.remove = __devexit_p(nuc900_i2c_remove),
.driver = {
.owner = THIS_MODULE,
.name = "nuc900-i2c0",
},
};
static int __init i2c_adap_nuc900_init(void)
{
return platform_driver_register(&nuc900_i2c_driver);
}
static void __exit i2c_adap_nuc900_exit(void)
{
platform_driver_unregister(&nuc900_i2c_driver);
}
subsys_initcall(i2c_adap_nuc900_init);
module_exit(i2c_adap_nuc900_exit);
MODULE_DESCRIPTION("NUC900 I2C Bus driver");
MODULE_AUTHOR("Wan ZongShun, <mcuos.com-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:nuc900-i2c0");

View File

@@ -1001,7 +1001,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
struct pxa_i2c *i2c;
struct resource *res;
struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
struct platform_device_id *id = platform_get_device_id(dev);
const struct platform_device_id *id = platform_get_device_id(dev);
int ret;
int irq;

View File

@@ -119,8 +119,10 @@ struct sh_mobile_i2c_data {
struct i2c_adapter adap;
struct clk *clk;
u_int8_t icic;
u_int8_t iccl;
u_int8_t icch;
u_int8_t flags;
spinlock_t lock;
wait_queue_head_t wait;
@@ -129,15 +131,17 @@ struct sh_mobile_i2c_data {
int sr;
};
#define IIC_FLAG_HAS_ICIC67 (1 << 0)
#define NORMAL_SPEED 100000 /* FAST_SPEED 400000 */
/* Register offsets */
#define ICDR(pd) (pd->reg + 0x00)
#define ICCR(pd) (pd->reg + 0x04)
#define ICSR(pd) (pd->reg + 0x08)
#define ICIC(pd) (pd->reg + 0x0c)
#define ICCL(pd) (pd->reg + 0x10)
#define ICCH(pd) (pd->reg + 0x14)
#define ICDR 0x00
#define ICCR 0x04
#define ICSR 0x08
#define ICIC 0x0c
#define ICCL 0x10
#define ICCH 0x14
/* Register bits */
#define ICCR_ICE 0x80
@@ -155,11 +159,32 @@ struct sh_mobile_i2c_data {
#define ICSR_WAIT 0x02
#define ICSR_DTE 0x01
#define ICIC_ICCLB8 0x80
#define ICIC_ICCHB8 0x40
#define ICIC_ALE 0x08
#define ICIC_TACKE 0x04
#define ICIC_WAITE 0x02
#define ICIC_DTEE 0x01
static void iic_wr(struct sh_mobile_i2c_data *pd, int offs, unsigned char data)
{
if (offs == ICIC)
data |= pd->icic;
iowrite8(data, pd->reg + offs);
}
static unsigned char iic_rd(struct sh_mobile_i2c_data *pd, int offs)
{
return ioread8(pd->reg + offs);
}
static void iic_set_clr(struct sh_mobile_i2c_data *pd, int offs,
unsigned char set, unsigned char clr)
{
iic_wr(pd, offs, (iic_rd(pd, offs) | set) & ~clr);
}
static void activate_ch(struct sh_mobile_i2c_data *pd)
{
unsigned long i2c_clk;
@@ -187,6 +212,14 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
else
pd->iccl = (u_int8_t)(num/denom);
/* one more bit of ICCL in ICIC */
if (pd->flags & IIC_FLAG_HAS_ICIC67) {
if ((num/denom) > 0xff)
pd->icic |= ICIC_ICCLB8;
else
pd->icic &= ~ICIC_ICCLB8;
}
/* Calculate the value for icch. From the data sheet:
icch = (p clock / transfer rate) * (H / (L + H)) */
num = i2c_clk * 4;
@@ -196,25 +229,33 @@ static void activate_ch(struct sh_mobile_i2c_data *pd)
else
pd->icch = (u_int8_t)(num/denom);
/* one more bit of ICCH in ICIC */
if (pd->flags & IIC_FLAG_HAS_ICIC67) {
if ((num/denom) > 0xff)
pd->icic |= ICIC_ICCHB8;
else
pd->icic &= ~ICIC_ICCHB8;
}
/* Enable channel and configure rx ack */
iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
iic_set_clr(pd, ICCR, ICCR_ICE, 0);
/* Mask all interrupts */
iowrite8(0, ICIC(pd));
iic_wr(pd, ICIC, 0);
/* Set the clock */
iowrite8(pd->iccl, ICCL(pd));
iowrite8(pd->icch, ICCH(pd));
iic_wr(pd, ICCL, pd->iccl);
iic_wr(pd, ICCH, pd->icch);
}
static void deactivate_ch(struct sh_mobile_i2c_data *pd)
{
/* Clear/disable interrupts */
iowrite8(0, ICSR(pd));
iowrite8(0, ICIC(pd));
iic_wr(pd, ICSR, 0);
iic_wr(pd, ICIC, 0);
/* Disable channel */
iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
iic_set_clr(pd, ICCR, 0, ICCR_ICE);
/* Disable clock and mark device as idle */
clk_disable(pd->clk);
@@ -233,35 +274,35 @@ static unsigned char i2c_op(struct sh_mobile_i2c_data *pd,
switch (op) {
case OP_START: /* issue start and trigger DTE interrupt */
iowrite8(0x94, ICCR(pd));
iic_wr(pd, ICCR, 0x94);
break;
case OP_TX_FIRST: /* disable DTE interrupt and write data */
iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE, ICIC(pd));
iowrite8(data, ICDR(pd));
iic_wr(pd, ICIC, ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
iic_wr(pd, ICDR, data);
break;
case OP_TX: /* write data */
iowrite8(data, ICDR(pd));
iic_wr(pd, ICDR, data);
break;
case OP_TX_STOP: /* write data and issue a stop afterwards */
iowrite8(data, ICDR(pd));
iowrite8(0x90, ICCR(pd));
iic_wr(pd, ICDR, data);
iic_wr(pd, ICCR, 0x90);
break;
case OP_TX_TO_RX: /* select read mode */
iowrite8(0x81, ICCR(pd));
iic_wr(pd, ICCR, 0x81);
break;
case OP_RX: /* just read data */
ret = ioread8(ICDR(pd));
ret = iic_rd(pd, ICDR);
break;
case OP_RX_STOP: /* enable DTE interrupt, issue stop */
iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE,
ICIC(pd));
iowrite8(0xc0, ICCR(pd));
iic_wr(pd, ICIC,
ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
iic_wr(pd, ICCR, 0xc0);
break;
case OP_RX_STOP_DATA: /* enable DTE interrupt, read data, issue stop */
iowrite8(ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE,
ICIC(pd));
ret = ioread8(ICDR(pd));
iowrite8(0xc0, ICCR(pd));
iic_wr(pd, ICIC,
ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
ret = iic_rd(pd, ICDR);
iic_wr(pd, ICCR, 0xc0);
break;
}
@@ -367,7 +408,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
unsigned char sr;
int wakeup;
sr = ioread8(ICSR(pd));
sr = iic_rd(pd, ICSR);
pd->sr |= sr; /* remember state */
dev_dbg(pd->dev, "i2c_isr 0x%02x 0x%02x %s %d %d!\n", sr, pd->sr,
@@ -376,7 +417,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
if (sr & (ICSR_AL | ICSR_TACK)) {
/* don't interrupt transaction - continue to issue stop */
iowrite8(sr & ~(ICSR_AL | ICSR_TACK), ICSR(pd));
iic_wr(pd, ICSR, sr & ~(ICSR_AL | ICSR_TACK));
wakeup = 0;
} else if (pd->msg->flags & I2C_M_RD)
wakeup = sh_mobile_i2c_isr_rx(pd);
@@ -384,7 +425,7 @@ static irqreturn_t sh_mobile_i2c_isr(int irq, void *dev_id)
wakeup = sh_mobile_i2c_isr_tx(pd);
if (sr & ICSR_WAIT) /* TODO: add delay here to support slow acks */
iowrite8(sr & ~ICSR_WAIT, ICSR(pd));
iic_wr(pd, ICSR, sr & ~ICSR_WAIT);
if (wakeup) {
pd->sr |= SW_DONE;
@@ -402,21 +443,21 @@ static int start_ch(struct sh_mobile_i2c_data *pd, struct i2c_msg *usr_msg)
}
/* Initialize channel registers */
iowrite8(ioread8(ICCR(pd)) & ~ICCR_ICE, ICCR(pd));
iic_set_clr(pd, ICCR, 0, ICCR_ICE);
/* Enable channel and configure rx ack */
iowrite8(ioread8(ICCR(pd)) | ICCR_ICE, ICCR(pd));
iic_set_clr(pd, ICCR, ICCR_ICE, 0);
/* Set the clock */
iowrite8(pd->iccl, ICCL(pd));
iowrite8(pd->icch, ICCH(pd));
iic_wr(pd, ICCL, pd->iccl);
iic_wr(pd, ICCH, pd->icch);
pd->msg = usr_msg;
pd->pos = -1;
pd->sr = 0;
/* Enable all interrupts to begin with */
iowrite8(ICIC_WAITE | ICIC_ALE | ICIC_TACKE | ICIC_DTEE, ICIC(pd));
iic_wr(pd, ICIC, ICIC_DTEE | ICIC_WAITE | ICIC_ALE | ICIC_TACKE);
return 0;
}
@@ -451,7 +492,7 @@ static int sh_mobile_i2c_xfer(struct i2c_adapter *adapter,
retry_count = 1000;
again:
val = ioread8(ICSR(pd));
val = iic_rd(pd, ICSR);
dev_dbg(pd->dev, "val 0x%02x pd->sr 0x%02x\n", val, pd->sr);
@@ -579,6 +620,12 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
goto err_irq;
}
/* The IIC blocks on SH-Mobile ARM processors
* come with two new bits in ICIC.
*/
if (size > 0x17)
pd->flags |= IIC_FLAG_HAS_ICIC67;
/* Enable Runtime PM for this device.
*
* Also tell the Runtime PM core to ignore children

View File

@@ -20,7 +20,9 @@
/* With some changes from Kyösti Mälkki <kmalkki@cc.hut.fi>.
All SMBus-related things are written by Frodo Looijaard <frodol@dds.nl>
SMBus 2.0 support by Mark Studebaker <mdsxyz123@yahoo.com> and
Jean Delvare <khali@linux-fr.org> */
Jean Delvare <khali@linux-fr.org>
Mux support by Rodolfo Giometti <giometti@enneenne.com> and
Michael Lawnick <michael.lawnick.ext@nsn.com> */
#include <linux/module.h>
#include <linux/kernel.h>
@@ -30,6 +32,8 @@
#include <linux/init.h>
#include <linux/idr.h>
#include <linux/mutex.h>
#include <linux/of_i2c.h>
#include <linux/of_device.h>
#include <linux/completion.h>
#include <linux/hardirq.h>
#include <linux/irqflags.h>
@@ -70,6 +74,10 @@ static int i2c_device_match(struct device *dev, struct device_driver *drv)
if (!client)
return 0;
/* Attempt an OF style match */
if (of_driver_match_device(dev, drv))
return 1;
driver = to_i2c_driver(drv);
/* match on an id table if there is one */
if (driver->id_table)
@@ -417,12 +425,88 @@ static int __i2c_check_addr_busy(struct device *dev, void *addrp)
return 0;
}
/* walk up mux tree */
static int i2c_check_mux_parents(struct i2c_adapter *adapter, int addr)
{
int result;
result = device_for_each_child(&adapter->dev, &addr,
__i2c_check_addr_busy);
if (!result && i2c_parent_is_i2c_adapter(adapter))
result = i2c_check_mux_parents(
to_i2c_adapter(adapter->dev.parent), addr);
return result;
}
/* recurse down mux tree */
static int i2c_check_mux_children(struct device *dev, void *addrp)
{
int result;
if (dev->type == &i2c_adapter_type)
result = device_for_each_child(dev, addrp,
i2c_check_mux_children);
else
result = __i2c_check_addr_busy(dev, addrp);
return result;
}
static int i2c_check_addr_busy(struct i2c_adapter *adapter, int addr)
{
return device_for_each_child(&adapter->dev, &addr,
__i2c_check_addr_busy);
int result = 0;
if (i2c_parent_is_i2c_adapter(adapter))
result = i2c_check_mux_parents(
to_i2c_adapter(adapter->dev.parent), addr);
if (!result)
result = device_for_each_child(&adapter->dev, &addr,
i2c_check_mux_children);
return result;
}
/**
* i2c_lock_adapter - Get exclusive access to an I2C bus segment
* @adapter: Target I2C bus segment
*/
void i2c_lock_adapter(struct i2c_adapter *adapter)
{
if (i2c_parent_is_i2c_adapter(adapter))
i2c_lock_adapter(to_i2c_adapter(adapter->dev.parent));
else
rt_mutex_lock(&adapter->bus_lock);
}
EXPORT_SYMBOL_GPL(i2c_lock_adapter);
/**
* i2c_trylock_adapter - Try to get exclusive access to an I2C bus segment
* @adapter: Target I2C bus segment
*/
static int i2c_trylock_adapter(struct i2c_adapter *adapter)
{
if (i2c_parent_is_i2c_adapter(adapter))
return i2c_trylock_adapter(to_i2c_adapter(adapter->dev.parent));
else
return rt_mutex_trylock(&adapter->bus_lock);
}
/**
* i2c_unlock_adapter - Release exclusive access to an I2C bus segment
* @adapter: Target I2C bus segment
*/
void i2c_unlock_adapter(struct i2c_adapter *adapter)
{
if (i2c_parent_is_i2c_adapter(adapter))
i2c_unlock_adapter(to_i2c_adapter(adapter->dev.parent));
else
rt_mutex_unlock(&adapter->bus_lock);
}
EXPORT_SYMBOL_GPL(i2c_unlock_adapter);
/**
* i2c_new_device - instantiate an i2c device
* @adap: the adapter managing the device
@@ -627,9 +711,9 @@ i2c_sysfs_new_device(struct device *dev, struct device_attribute *attr,
return -EINVAL;
/* Keep track of the added device */
i2c_lock_adapter(adap);
mutex_lock(&adap->userspace_clients_lock);
list_add_tail(&client->detected, &adap->userspace_clients);
i2c_unlock_adapter(adap);
mutex_unlock(&adap->userspace_clients_lock);
dev_info(dev, "%s: Instantiated device %s at 0x%02hx\n", "new_device",
info.type, info.addr);
@@ -668,7 +752,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
/* Make sure the device was added through sysfs */
res = -ENOENT;
i2c_lock_adapter(adap);
mutex_lock(&adap->userspace_clients_lock);
list_for_each_entry_safe(client, next, &adap->userspace_clients,
detected) {
if (client->addr == addr) {
@@ -681,7 +765,7 @@ i2c_sysfs_delete_device(struct device *dev, struct device_attribute *attr,
break;
}
}
i2c_unlock_adapter(adap);
mutex_unlock(&adap->userspace_clients_lock);
if (res < 0)
dev_err(dev, "%s: Can't find device in list\n",
@@ -708,10 +792,11 @@ static const struct attribute_group *i2c_adapter_attr_groups[] = {
NULL
};
static struct device_type i2c_adapter_type = {
struct device_type i2c_adapter_type = {
.groups = i2c_adapter_attr_groups,
.release = i2c_adapter_dev_release,
};
EXPORT_SYMBOL_GPL(i2c_adapter_type);
#ifdef CONFIG_I2C_COMPAT
static struct class_compat *i2c_adapter_compat_class;
@@ -754,7 +839,7 @@ static int __process_new_adapter(struct device_driver *d, void *data)
static int i2c_register_adapter(struct i2c_adapter *adap)
{
int res = 0, dummy;
int res = 0;
/* Can't register until after driver model init */
if (unlikely(WARN_ON(!i2c_bus_type.p))) {
@@ -763,6 +848,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
}
rt_mutex_init(&adap->bus_lock);
mutex_init(&adap->userspace_clients_lock);
INIT_LIST_HEAD(&adap->userspace_clients);
/* Set default timeout to 1 second if not already set */
@@ -790,10 +876,12 @@ static int i2c_register_adapter(struct i2c_adapter *adap)
if (adap->nr < __i2c_first_dynamic_bus_num)
i2c_scan_static_board_info(adap);
/* Register devices from the device tree */
of_i2c_register_devices(adap);
/* Notify drivers */
mutex_lock(&core_lock);
dummy = bus_for_each_drv(&i2c_bus_type, NULL, adap,
__process_new_adapter);
bus_for_each_drv(&i2c_bus_type, NULL, adap, __process_new_adapter);
mutex_unlock(&core_lock);
return 0;
@@ -966,7 +1054,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
return res;
/* Remove devices instantiated from sysfs */
i2c_lock_adapter(adap);
mutex_lock(&adap->userspace_clients_lock);
list_for_each_entry_safe(client, next, &adap->userspace_clients,
detected) {
dev_dbg(&adap->dev, "Removing %s at 0x%x\n", client->name,
@@ -974,7 +1062,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
list_del(&client->detected);
i2c_unregister_device(client);
}
i2c_unlock_adapter(adap);
mutex_unlock(&adap->userspace_clients_lock);
/* Detach any active clients. This can't fail, thus we do not
checking the returned value. */
@@ -1229,12 +1317,12 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
#endif
if (in_atomic() || irqs_disabled()) {
ret = rt_mutex_trylock(&adap->bus_lock);
ret = i2c_trylock_adapter(adap);
if (!ret)
/* I2C activity is ongoing. */
return -EAGAIN;
} else {
rt_mutex_lock(&adap->bus_lock);
i2c_lock_adapter(adap);
}
/* Retry automatically on arbitration loss */
@@ -1246,7 +1334,7 @@ int i2c_transfer(struct i2c_adapter *adap, struct i2c_msg *msgs, int num)
if (time_after(jiffies, orig_jiffies + adap->timeout))
break;
}
rt_mutex_unlock(&adap->bus_lock);
i2c_unlock_adapter(adap);
return ret;
} else {
@@ -1341,13 +1429,17 @@ static int i2c_default_probe(struct i2c_adapter *adap, unsigned short addr)
I2C_SMBUS_BYTE_DATA, &dummy);
else
#endif
if ((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50
|| !i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
I2C_SMBUS_BYTE, &dummy);
else
if (!((addr & ~0x07) == 0x30 || (addr & ~0x0f) == 0x50)
&& i2c_check_functionality(adap, I2C_FUNC_SMBUS_QUICK))
err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_WRITE, 0,
I2C_SMBUS_QUICK, NULL);
else if (i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE))
err = i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
I2C_SMBUS_BYTE, &dummy);
else {
dev_warn(&adap->dev, "No suitable probing method supported\n");
err = -EOPNOTSUPP;
}
return err >= 0;
}
@@ -1428,16 +1520,6 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
if (!(adapter->class & driver->class))
goto exit_free;
/* Stop here if the bus doesn't support probing */
if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_READ_BYTE)) {
if (address_list[0] == I2C_CLIENT_END)
goto exit_free;
dev_warn(&adapter->dev, "Probing not supported\n");
err = -EOPNOTSUPP;
goto exit_free;
}
for (i = 0; address_list[i] != I2C_CLIENT_END; i += 1) {
dev_dbg(&adapter->dev, "found normal entry for adapter %d, "
"addr 0x%02x\n", adap_id, address_list[i]);
@@ -1452,18 +1534,23 @@ static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver)
return err;
}
int i2c_probe_func_quick_read(struct i2c_adapter *adap, unsigned short addr)
{
return i2c_smbus_xfer(adap, addr, 0, I2C_SMBUS_READ, 0,
I2C_SMBUS_QUICK, NULL) >= 0;
}
EXPORT_SYMBOL_GPL(i2c_probe_func_quick_read);
struct i2c_client *
i2c_new_probed_device(struct i2c_adapter *adap,
struct i2c_board_info *info,
unsigned short const *addr_list)
unsigned short const *addr_list,
int (*probe)(struct i2c_adapter *, unsigned short addr))
{
int i;
/* Stop here if the bus doesn't support probing */
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_READ_BYTE)) {
dev_err(&adap->dev, "Probing not supported\n");
return NULL;
}
if (!probe)
probe = i2c_default_probe;
for (i = 0; addr_list[i] != I2C_CLIENT_END; i++) {
/* Check address validity */
@@ -1481,7 +1568,7 @@ i2c_new_probed_device(struct i2c_adapter *adap,
}
/* Test address responsiveness */
if (i2c_default_probe(adap, addr_list[i]))
if (probe(adap, addr_list[i]))
break;
}
@@ -1993,7 +2080,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
if (adapter->algo->smbus_xfer) {
rt_mutex_lock(&adapter->bus_lock);
i2c_lock_adapter(adapter);
/* Retry automatically on arbitration loss */
orig_jiffies = jiffies;
@@ -2007,7 +2094,7 @@ s32 i2c_smbus_xfer(struct i2c_adapter *adapter, u16 addr, unsigned short flags,
orig_jiffies + adapter->timeout))
break;
}
rt_mutex_unlock(&adapter->bus_lock);
i2c_unlock_adapter(adapter);
} else
res = i2c_smbus_xfer_emulated(adapter, addr, flags, read_write,
command, protocol, data);

View File

@@ -167,13 +167,9 @@ static ssize_t i2cdev_write(struct file *file, const char __user *buf,
if (count > 8192)
count = 8192;
tmp = kmalloc(count, GFP_KERNEL);
if (tmp == NULL)
return -ENOMEM;
if (copy_from_user(tmp, buf, count)) {
kfree(tmp);
return -EFAULT;
}
tmp = memdup_user(buf, count);
if (IS_ERR(tmp))
return PTR_ERR(tmp);
pr_debug("i2c-dev: i2c-%d writing %zu bytes.\n",
iminor(file->f_path.dentry->d_inode), count);
@@ -193,12 +189,50 @@ static int i2cdev_check(struct device *dev, void *addrp)
return dev->driver ? -EBUSY : 0;
}
/* walk up mux tree */
static int i2cdev_check_mux_parents(struct i2c_adapter *adapter, int addr)
{
int result;
result = device_for_each_child(&adapter->dev, &addr, i2cdev_check);
if (!result && i2c_parent_is_i2c_adapter(adapter))
result = i2cdev_check_mux_parents(
to_i2c_adapter(adapter->dev.parent), addr);
return result;
}
/* recurse down mux tree */
static int i2cdev_check_mux_children(struct device *dev, void *addrp)
{
int result;
if (dev->type == &i2c_adapter_type)
result = device_for_each_child(dev, addrp,
i2cdev_check_mux_children);
else
result = i2cdev_check(dev, addrp);
return result;
}
/* This address checking function differs from the one in i2c-core
in that it considers an address with a registered device, but no
driver bound to it, as NOT busy. */
static int i2cdev_check_addr(struct i2c_adapter *adapter, unsigned int addr)
{
return device_for_each_child(&adapter->dev, &addr, i2cdev_check);
int result = 0;
if (i2c_parent_is_i2c_adapter(adapter))
result = i2cdev_check_mux_parents(
to_i2c_adapter(adapter->dev.parent), addr);
if (!result)
result = device_for_each_child(&adapter->dev, &addr,
i2cdev_check_mux_children);
return result;
}
static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
@@ -219,9 +253,7 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
if (rdwr_arg.nmsgs > I2C_RDRW_IOCTL_MAX_MSGS)
return -EINVAL;
rdwr_pa = (struct i2c_msg *)
kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg),
GFP_KERNEL);
rdwr_pa = kmalloc(rdwr_arg.nmsgs * sizeof(struct i2c_msg), GFP_KERNEL);
if (!rdwr_pa)
return -ENOMEM;
@@ -247,15 +279,9 @@ static noinline int i2cdev_ioctl_rdrw(struct i2c_client *client,
break;
}
data_ptrs[i] = (u8 __user *)rdwr_pa[i].buf;
rdwr_pa[i].buf = kmalloc(rdwr_pa[i].len, GFP_KERNEL);
if (rdwr_pa[i].buf == NULL) {
res = -ENOMEM;
break;
}
if (copy_from_user(rdwr_pa[i].buf, data_ptrs[i],
rdwr_pa[i].len)) {
++i; /* Needs to be kfreed too */
res = -EFAULT;
rdwr_pa[i].buf = memdup_user(data_ptrs[i], rdwr_pa[i].len);
if (IS_ERR(rdwr_pa[i].buf)) {
res = PTR_ERR(rdwr_pa[i].buf);
break;
}
}

165
drivers/i2c/i2c-mux.c Normal file
View File

@@ -0,0 +1,165 @@
/*
* Multiplexed I2C bus driver.
*
* Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
* Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
* Copyright (c) 2009-2010 NSN GmbH & Co KG <michael.lawnick.ext@nsn.com>
*
* Simplifies access to complex multiplexed I2C bus topologies, by presenting
* each multiplexed bus segment as an additional I2C adapter.
* Supports multi-level mux'ing (mux behind a mux).
*
* Based on:
* i2c-virt.c from Kumar Gala <galak@kernel.crashing.org>
* i2c-virtual.c from Ken Harrenstien, Copyright (c) 2004 Google, Inc.
* i2c-virtual.c from Brian Kuschak <bkuschak@yahoo.com>
*
* 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/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
/* multiplexer per channel data */
struct i2c_mux_priv {
struct i2c_adapter adap;
struct i2c_algorithm algo;
struct i2c_adapter *parent;
void *mux_dev; /* the mux chip/device */
u32 chan_id; /* the channel id */
int (*select)(struct i2c_adapter *, void *mux_dev, u32 chan_id);
int (*deselect)(struct i2c_adapter *, void *mux_dev, u32 chan_id);
};
static int i2c_mux_master_xfer(struct i2c_adapter *adap,
struct i2c_msg msgs[], int num)
{
struct i2c_mux_priv *priv = adap->algo_data;
struct i2c_adapter *parent = priv->parent;
int ret;
/* Switch to the right mux port and perform the transfer. */
ret = priv->select(parent, priv->mux_dev, priv->chan_id);
if (ret >= 0)
ret = parent->algo->master_xfer(parent, msgs, num);
if (priv->deselect)
priv->deselect(parent, priv->mux_dev, priv->chan_id);
return ret;
}
static int i2c_mux_smbus_xfer(struct i2c_adapter *adap,
u16 addr, unsigned short flags,
char read_write, u8 command,
int size, union i2c_smbus_data *data)
{
struct i2c_mux_priv *priv = adap->algo_data;
struct i2c_adapter *parent = priv->parent;
int ret;
/* Select the right mux port and perform the transfer. */
ret = priv->select(parent, priv->mux_dev, priv->chan_id);
if (ret >= 0)
ret = parent->algo->smbus_xfer(parent, addr, flags,
read_write, command, size, data);
if (priv->deselect)
priv->deselect(parent, priv->mux_dev, priv->chan_id);
return ret;
}
/* Return the parent's functionality */
static u32 i2c_mux_functionality(struct i2c_adapter *adap)
{
struct i2c_mux_priv *priv = adap->algo_data;
struct i2c_adapter *parent = priv->parent;
return parent->algo->functionality(parent);
}
struct i2c_adapter *i2c_add_mux_adapter(struct i2c_adapter *parent,
void *mux_dev, u32 force_nr, u32 chan_id,
int (*select) (struct i2c_adapter *,
void *, u32),
int (*deselect) (struct i2c_adapter *,
void *, u32))
{
struct i2c_mux_priv *priv;
int ret;
priv = kzalloc(sizeof(struct i2c_mux_priv), GFP_KERNEL);
if (!priv)
return NULL;
/* Set up private adapter data */
priv->parent = parent;
priv->mux_dev = mux_dev;
priv->chan_id = chan_id;
priv->select = select;
priv->deselect = deselect;
/* Need to do algo dynamically because we don't know ahead
* of time what sort of physical adapter we'll be dealing with.
*/
if (parent->algo->master_xfer)
priv->algo.master_xfer = i2c_mux_master_xfer;
if (parent->algo->smbus_xfer)
priv->algo.smbus_xfer = i2c_mux_smbus_xfer;
priv->algo.functionality = i2c_mux_functionality;
/* Now fill out new adapter structure */
snprintf(priv->adap.name, sizeof(priv->adap.name),
"i2c-%d-mux (chan_id %d)", i2c_adapter_id(parent), chan_id);
priv->adap.owner = THIS_MODULE;
priv->adap.id = parent->id;
priv->adap.algo = &priv->algo;
priv->adap.algo_data = priv;
priv->adap.dev.parent = &parent->dev;
if (force_nr) {
priv->adap.nr = force_nr;
ret = i2c_add_numbered_adapter(&priv->adap);
} else {
ret = i2c_add_adapter(&priv->adap);
}
if (ret < 0) {
dev_err(&parent->dev,
"failed to add mux-adapter (error=%d)\n",
ret);
kfree(priv);
return NULL;
}
dev_info(&parent->dev, "Added multiplexed i2c bus %d\n",
i2c_adapter_id(&priv->adap));
return &priv->adap;
}
EXPORT_SYMBOL_GPL(i2c_add_mux_adapter);
int i2c_del_mux_adapter(struct i2c_adapter *adap)
{
struct i2c_mux_priv *priv = adap->algo_data;
int ret;
ret = i2c_del_adapter(adap);
if (ret < 0)
return ret;
kfree(priv);
return 0;
}
EXPORT_SYMBOL_GPL(i2c_del_mux_adapter);
MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
MODULE_DESCRIPTION("I2C driver for multiplexed I2C busses");
MODULE_LICENSE("GPL v2");

18
drivers/i2c/muxes/Kconfig Normal file
View File

@@ -0,0 +1,18 @@
#
# Multiplexer I2C chip drivers configuration
#
menu "Multiplexer I2C Chip support"
depends on I2C_MUX
config I2C_MUX_PCA954x
tristate "Philips PCA954x I2C Mux/switches"
depends on EXPERIMENTAL
help
If you say yes here you get support for the Philips PCA954x
I2C mux/switch devices.
This driver can also be built as a module. If so, the module
will be called pca954x.
endmenu

View File

@@ -0,0 +1,8 @@
#
# Makefile for multiplexer I2C chip drivers.
obj-$(CONFIG_I2C_MUX_PCA954x) += pca954x.o
ifeq ($(CONFIG_I2C_DEBUG_BUS),y)
EXTRA_CFLAGS += -DDEBUG
endif

301
drivers/i2c/muxes/pca954x.c Normal file
View File

@@ -0,0 +1,301 @@
/*
* I2C multiplexer
*
* Copyright (c) 2008-2009 Rodolfo Giometti <giometti@linux.it>
* Copyright (c) 2008-2009 Eurotech S.p.A. <info@eurotech.it>
*
* This module supports the PCA954x series of I2C multiplexer/switch chips
* made by Philips Semiconductors.
* This includes the:
* PCA9540, PCA9542, PCA9543, PCA9544, PCA9545, PCA9546, PCA9547
* and PCA9548.
*
* These chips are all controlled via the I2C bus itself, and all have a
* single 8-bit register. The upstream "parent" bus fans out to two,
* four, or eight downstream busses or channels; which of these
* are selected is determined by the chip type and register contents. A
* mux can select only one sub-bus at a time; a switch can select any
* combination simultaneously.
*
* Based on:
* pca954x.c from Kumar Gala <galak@kernel.crashing.org>
* Copyright (C) 2006
*
* Based on:
* pca954x.c from Ken Harrenstien
* Copyright (C) 2004 Google, Inc. (Ken Harrenstien)
*
* Based on:
* i2c-virtual_cb.c from Brian Kuschak <bkuschak@yahoo.com>
* and
* pca9540.c from Jean Delvare <khali@linux-fr.org>.
*
* 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/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/i2c-mux.h>
#include <linux/i2c/pca954x.h>
#define PCA954X_MAX_NCHANS 8
enum pca_type {
pca_9540,
pca_9542,
pca_9543,
pca_9544,
pca_9545,
pca_9546,
pca_9547,
pca_9548,
};
struct pca954x {
enum pca_type type;
struct i2c_adapter *virt_adaps[PCA954X_MAX_NCHANS];
u8 last_chan; /* last register value */
};
struct chip_desc {
u8 nchans;
u8 enable; /* used for muxes only */
enum muxtype {
pca954x_ismux = 0,
pca954x_isswi
} muxtype;
};
/* Provide specs for the PCA954x types we know about */
static const struct chip_desc chips[] = {
[pca_9540] = {
.nchans = 2,
.enable = 0x4,
.muxtype = pca954x_ismux,
},
[pca_9543] = {
.nchans = 2,
.muxtype = pca954x_isswi,
},
[pca_9544] = {
.nchans = 4,
.enable = 0x4,
.muxtype = pca954x_ismux,
},
[pca_9545] = {
.nchans = 4,
.muxtype = pca954x_isswi,
},
[pca_9547] = {
.nchans = 8,
.enable = 0x8,
.muxtype = pca954x_ismux,
},
[pca_9548] = {
.nchans = 8,
.muxtype = pca954x_isswi,
},
};
static const struct i2c_device_id pca954x_id[] = {
{ "pca9540", pca_9540 },
{ "pca9542", pca_9540 },
{ "pca9543", pca_9543 },
{ "pca9544", pca_9544 },
{ "pca9545", pca_9545 },
{ "pca9546", pca_9545 },
{ "pca9547", pca_9547 },
{ "pca9548", pca_9548 },
{ }
};
MODULE_DEVICE_TABLE(i2c, pca954x_id);
/* Write to mux register. Don't use i2c_transfer()/i2c_smbus_xfer()
for this as they will try to lock adapter a second time */
static int pca954x_reg_write(struct i2c_adapter *adap,
struct i2c_client *client, u8 val)
{
int ret = -ENODEV;
if (adap->algo->master_xfer) {
struct i2c_msg msg;
char buf[1];
msg.addr = client->addr;
msg.flags = 0;
msg.len = 1;
buf[0] = val;
msg.buf = buf;
ret = adap->algo->master_xfer(adap, &msg, 1);
} else {
union i2c_smbus_data data;
ret = adap->algo->smbus_xfer(adap, client->addr,
client->flags,
I2C_SMBUS_WRITE,
val, I2C_SMBUS_BYTE, &data);
}
return ret;
}
static int pca954x_select_chan(struct i2c_adapter *adap,
void *client, u32 chan)
{
struct pca954x *data = i2c_get_clientdata(client);
const struct chip_desc *chip = &chips[data->type];
u8 regval;
int ret = 0;
/* we make switches look like muxes, not sure how to be smarter */
if (chip->muxtype == pca954x_ismux)
regval = chan | chip->enable;
else
regval = 1 << chan;
/* Only select the channel if its different from the last channel */
if (data->last_chan != regval) {
ret = pca954x_reg_write(adap, client, regval);
data->last_chan = regval;
}
return ret;
}
static int pca954x_deselect_mux(struct i2c_adapter *adap,
void *client, u32 chan)
{
struct pca954x *data = i2c_get_clientdata(client);
/* Deselect active channel */
data->last_chan = 0;
return pca954x_reg_write(adap, client, data->last_chan);
}
/*
* I2C init/probing/exit functions
*/
static int __devinit pca954x_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct i2c_adapter *adap = to_i2c_adapter(client->dev.parent);
struct pca954x_platform_data *pdata = client->dev.platform_data;
int num, force;
struct pca954x *data;
int ret = -ENODEV;
if (!i2c_check_functionality(adap, I2C_FUNC_SMBUS_BYTE))
goto err;
data = kzalloc(sizeof(struct pca954x), GFP_KERNEL);
if (!data) {
ret = -ENOMEM;
goto err;
}
i2c_set_clientdata(client, data);
/* Read the mux register at addr to verify
* that the mux is in fact present.
*/
if (i2c_smbus_read_byte(client) < 0) {
dev_warn(&client->dev, "probe failed\n");
goto exit_free;
}
data->type = id->driver_data;
data->last_chan = 0; /* force the first selection */
/* Now create an adapter for each channel */
for (num = 0; num < chips[data->type].nchans; num++) {
force = 0; /* dynamic adap number */
if (pdata) {
if (num < pdata->num_modes)
/* force static number */
force = pdata->modes[num].adap_id;
else
/* discard unconfigured channels */
break;
}
data->virt_adaps[num] =
i2c_add_mux_adapter(adap, client,
force, num, pca954x_select_chan,
(pdata && pdata->modes[num].deselect_on_exit)
? pca954x_deselect_mux : NULL);
if (data->virt_adaps[num] == NULL) {
ret = -ENODEV;
dev_err(&client->dev,
"failed to register multiplexed adapter"
" %d as bus %d\n", num, force);
goto virt_reg_failed;
}
}
dev_info(&client->dev,
"registered %d multiplexed busses for I2C %s %s\n",
num, chips[data->type].muxtype == pca954x_ismux
? "mux" : "switch", client->name);
return 0;
virt_reg_failed:
for (num--; num >= 0; num--)
i2c_del_mux_adapter(data->virt_adaps[num]);
exit_free:
kfree(data);
err:
return ret;
}
static int __devexit pca954x_remove(struct i2c_client *client)
{
struct pca954x *data = i2c_get_clientdata(client);
const struct chip_desc *chip = &chips[data->type];
int i, err;
for (i = 0; i < chip->nchans; ++i)
if (data->virt_adaps[i]) {
err = i2c_del_mux_adapter(data->virt_adaps[i]);
if (err)
return err;
data->virt_adaps[i] = NULL;
}
kfree(data);
return 0;
}
static struct i2c_driver pca954x_driver = {
.driver = {
.name = "pca954x",
.owner = THIS_MODULE,
},
.probe = pca954x_probe,
.remove = __devexit_p(pca954x_remove),
.id_table = pca954x_id,
};
static int __init pca954x_init(void)
{
return i2c_add_driver(&pca954x_driver);
}
static void __exit pca954x_exit(void)
{
i2c_del_driver(&pca954x_driver);
}
module_init(pca954x_init);
module_exit(pca954x_exit);
MODULE_AUTHOR("Rodolfo Giometti <giometti@linux.it>");
MODULE_DESCRIPTION("PCA954x I2C mux/switch driver");
MODULE_LICENSE("GPL v2");