Commit dd04265b authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus/i2c' of git://git.fluff.org/bjdooks/linux

* 'for-linus/i2c' of git://git.fluff.org/bjdooks/linux:
  i2c: Add support for Xilinx XPS IIC Bus Interface
  i2c: omap: Add support for 16-bit registers
  i2c-pnx: fix setting start/stop condition
  powerpc: doc/dts-bindings: update doc of FSL I2C bindings
  i2c-mpc: add support for the MPC512x processors from Freescale
  i2c-mpc: rename "setclock" initialization functions to "setup"
  i2c-mpc: use __devinit[data] for initialization functions and data
  i2c/imx: don't add probe function to the driver struct
  i2c: Add support for Ux500/Nomadik I2C controller
parents 6dc3eb5c 3f4ae860
...@@ -2,15 +2,14 @@ ...@@ -2,15 +2,14 @@
Required properties : Required properties :
- device_type : Should be "i2c"
- reg : Offset and length of the register set for the device - reg : Offset and length of the register set for the device
- compatible : should be "fsl,CHIP-i2c" where CHIP is the name of a
compatible processor, e.g. mpc8313, mpc8543, mpc8544, mpc5121,
mpc5200 or mpc5200b. For the mpc5121, an additional node
"fsl,mpc5121-i2c-ctrl" is required as shown in the example below.
Recommended properties : Recommended properties :
- compatible : compatibility list with 2 entries, the first should
be "fsl,CHIP-i2c" where CHIP is the name of a compatible processor,
e.g. mpc8313, mpc8543, mpc8544, mpc5200 or mpc5200b. The second one
should be "fsl-i2c".
- interrupts : <a b> where a is the interrupt number and b is a - interrupts : <a b> where a is the interrupt number and b is a
field that represents an encoding of the sense and level field that represents an encoding of the sense and level
information for the interrupt. This should be encoded based on information for the interrupt. This should be encoded based on
...@@ -24,25 +23,40 @@ Recommended properties : ...@@ -24,25 +23,40 @@ Recommended properties :
Examples : Examples :
/* MPC5121 based board */
i2c@1740 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,mpc5121-i2c", "fsl-i2c";
reg = <0x1740 0x20>;
interrupts = <11 0x8>;
interrupt-parent = <&ipic>;
clock-frequency = <100000>;
};
i2ccontrol@1760 {
compatible = "fsl,mpc5121-i2c-ctrl";
reg = <0x1760 0x8>;
};
/* MPC5200B based board */
i2c@3d00 { i2c@3d00 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c"; compatible = "fsl,mpc5200b-i2c","fsl,mpc5200-i2c","fsl-i2c";
cell-index = <0>;
reg = <0x3d00 0x40>; reg = <0x3d00 0x40>;
interrupts = <2 15 0>; interrupts = <2 15 0>;
interrupt-parent = <&mpc5200_pic>; interrupt-parent = <&mpc5200_pic>;
fsl,preserve-clocking; fsl,preserve-clocking;
}; };
/* MPC8544 base board */
i2c@3100 { i2c@3100 {
#address-cells = <1>; #address-cells = <1>;
#size-cells = <0>; #size-cells = <0>;
cell-index = <1>;
compatible = "fsl,mpc8544-i2c", "fsl-i2c"; compatible = "fsl,mpc8544-i2c", "fsl-i2c";
reg = <0x3100 0x100>; reg = <0x3100 0x100>;
interrupts = <43 2>; interrupts = <43 2>;
interrupt-parent = <&mpic>; interrupt-parent = <&mpic>;
clock-frequency = <400000>; clock-frequency = <400000>;
}; };
...@@ -421,13 +421,12 @@ config I2C_IXP2000 ...@@ -421,13 +421,12 @@ config I2C_IXP2000
instead. instead.
config I2C_MPC config I2C_MPC
tristate "MPC107/824x/85xx/52xx/86xx" tristate "MPC107/824x/85xx/512x/52xx/83xx/86xx"
depends on PPC32 depends on PPC32
help help
If you say yes to this option, support will be included for the If you say yes to this option, support will be included for the
built-in I2C interface on the MPC107/Tsi107/MPC8240/MPC8245 and built-in I2C interface on the MPC107, Tsi107, MPC512x, MPC52xx,
MPC85xx/MPC8641 family processors. The driver may also work on 52xx MPC8240, MPC8245, MPC83xx, MPC85xx and MPC8641 family processors.
family processors, though interrupts are known not to work.
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-mpc. will be called i2c-mpc.
...@@ -442,6 +441,13 @@ config I2C_MV64XXX ...@@ -442,6 +441,13 @@ config I2C_MV64XXX
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-mv64xxx. will be called i2c-mv64xxx.
config I2C_NOMADIK
tristate "ST-Ericsson Nomadik/Ux500 I2C Controller"
depends on PLAT_NOMADIK
help
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_OCORES config I2C_OCORES
tristate "OpenCores I2C Controller" tristate "OpenCores I2C Controller"
depends on EXPERIMENTAL depends on EXPERIMENTAL
...@@ -577,6 +583,16 @@ config I2C_OCTEON ...@@ -577,6 +583,16 @@ config I2C_OCTEON
This driver can also be built as a module. If so, the module This driver can also be built as a module. If so, the module
will be called i2c-octeon. will be called i2c-octeon.
config I2C_XILINX
tristate "Xilinx I2C Controller"
depends on EXPERIMENTAL && HAS_IOMEM
help
If you say yes to this option, support will be included for the
Xilinx I2C controller.
This driver can also be built as a module. If so, the module
will be called xilinx_i2c.
comment "External I2C/SMBus adapter drivers" comment "External I2C/SMBus adapter drivers"
config I2C_PARPORT config I2C_PARPORT
......
...@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o ...@@ -42,6 +42,7 @@ obj-$(CONFIG_I2C_IOP3XX) += i2c-iop3xx.o
obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o obj-$(CONFIG_I2C_IXP2000) += i2c-ixp2000.o
obj-$(CONFIG_I2C_MPC) += i2c-mpc.o obj-$(CONFIG_I2C_MPC) += i2c-mpc.o
obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o obj-$(CONFIG_I2C_MV64XXX) += i2c-mv64xxx.o
obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o
obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o
obj-$(CONFIG_I2C_OMAP) += i2c-omap.o obj-$(CONFIG_I2C_OMAP) += i2c-omap.o
obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o obj-$(CONFIG_I2C_PASEMI) += i2c-pasemi.o
...@@ -55,6 +56,7 @@ obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o ...@@ -55,6 +56,7 @@ obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o
obj-$(CONFIG_I2C_STU300) += i2c-stu300.o obj-$(CONFIG_I2C_STU300) += i2c-stu300.o
obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o obj-$(CONFIG_I2C_VERSATILE) += i2c-versatile.o
obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o obj-$(CONFIG_I2C_OCTEON) += i2c-octeon.o
obj-$(CONFIG_I2C_XILINX) += i2c-xiic.o
# External I2C/SMBus adapter drivers # External I2C/SMBus adapter drivers
obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o obj-$(CONFIG_I2C_PARPORT) += i2c-parport.o
......
...@@ -627,7 +627,6 @@ static int __exit i2c_imx_remove(struct platform_device *pdev) ...@@ -627,7 +627,6 @@ static int __exit i2c_imx_remove(struct platform_device *pdev)
} }
static struct platform_driver i2c_imx_driver = { static struct platform_driver i2c_imx_driver = {
.probe = i2c_imx_probe,
.remove = __exit_p(i2c_imx_remove), .remove = __exit_p(i2c_imx_remove),
.driver = { .driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#define DRV_NAME "mpc-i2c" #define DRV_NAME "mpc-i2c"
#define MPC_I2C_CLOCK_LEGACY 0
#define MPC_I2C_CLOCK_PRESERVE (~0U)
#define MPC_I2C_FDR 0x04 #define MPC_I2C_FDR 0x04
#define MPC_I2C_CR 0x08 #define MPC_I2C_CR 0x08
#define MPC_I2C_SR 0x0c #define MPC_I2C_SR 0x0c
...@@ -66,9 +69,8 @@ struct mpc_i2c_divider { ...@@ -66,9 +69,8 @@ struct mpc_i2c_divider {
u16 fdr; /* including dfsrr */ u16 fdr; /* including dfsrr */
}; };
struct mpc_i2c_match_data { struct mpc_i2c_data {
void (*setclock)(struct device_node *node, void (*setup)(struct device_node *node, struct mpc_i2c *i2c,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler); u32 clock, u32 prescaler);
u32 prescaler; u32 prescaler;
}; };
...@@ -164,8 +166,8 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing) ...@@ -164,8 +166,8 @@ static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)
return 0; return 0;
} }
#ifdef CONFIG_PPC_MPC52xx #if defined(CONFIG_PPC_MPC52xx) || defined(CONFIG_PPC_MPC512x)
static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] __devinitconst = {
{20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23}, {20, 0x20}, {22, 0x21}, {24, 0x22}, {26, 0x23},
{28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02}, {28, 0x24}, {30, 0x01}, {32, 0x25}, {34, 0x02},
{36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28}, {36, 0x26}, {40, 0x27}, {44, 0x04}, {48, 0x28},
...@@ -186,14 +188,15 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = { ...@@ -186,14 +188,15 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_52xx[] = {
{10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f} {10240, 0x9d}, {12288, 0x9e}, {15360, 0x9f}
}; };
int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler) static int __devinit mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock,
int prescaler)
{ {
const struct mpc_i2c_divider *div = NULL; const struct mpc_i2c_divider *div = NULL;
unsigned int pvr = mfspr(SPRN_PVR); unsigned int pvr = mfspr(SPRN_PVR);
u32 divider; u32 divider;
int i; int i;
if (!clock) if (clock == MPC_I2C_CLOCK_LEGACY)
return -EINVAL; return -EINVAL;
/* Determine divider value */ /* Determine divider value */
...@@ -215,12 +218,18 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler) ...@@ -215,12 +218,18 @@ int mpc_i2c_get_fdr_52xx(struct device_node *node, u32 clock, int prescaler)
return div ? (int)div->fdr : -EINVAL; return div ? (int)div->fdr : -EINVAL;
} }
static void mpc_i2c_setclock_52xx(struct device_node *node, static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
struct mpc_i2c *i2c, struct mpc_i2c *i2c,
u32 clock, u32 prescaler) u32 clock, u32 prescaler)
{ {
int ret, fdr; int ret, fdr;
if (clock == MPC_I2C_CLOCK_PRESERVE) {
dev_dbg(i2c->dev, "using fdr %d\n",
readb(i2c->base + MPC_I2C_FDR));
return;
}
ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler); ret = mpc_i2c_get_fdr_52xx(node, clock, prescaler);
fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */ fdr = (ret >= 0) ? ret : 0x3f; /* backward compatibility */
...@@ -229,16 +238,52 @@ static void mpc_i2c_setclock_52xx(struct device_node *node, ...@@ -229,16 +238,52 @@ static void mpc_i2c_setclock_52xx(struct device_node *node,
if (ret >= 0) if (ret >= 0)
dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr); dev_info(i2c->dev, "clock %d Hz (fdr=%d)\n", clock, fdr);
} }
#else /* !CONFIG_PPC_MPC52xx */ #else /* !(CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x) */
static void mpc_i2c_setclock_52xx(struct device_node *node, static void __devinit mpc_i2c_setup_52xx(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
}
#endif /* CONFIG_PPC_MPC52xx || CONFIG_PPC_MPC512x */
#ifdef CONFIG_PPC_MPC512x
static void __devinit mpc_i2c_setup_512x(struct device_node *node,
struct mpc_i2c *i2c,
u32 clock, u32 prescaler)
{
struct device_node *node_ctrl;
void __iomem *ctrl;
const u32 *pval;
u32 idx;
/* Enable I2C interrupts for mpc5121 */
node_ctrl = of_find_compatible_node(NULL, NULL,
"fsl,mpc5121-i2c-ctrl");
if (node_ctrl) {
ctrl = of_iomap(node_ctrl, 0);
if (ctrl) {
/* Interrupt enable bits for i2c-0/1/2: bit 24/26/28 */
pval = of_get_property(node, "reg", NULL);
idx = (*pval & 0xff) / 0x20;
setbits32(ctrl, 1 << (24 + idx * 2));
iounmap(ctrl);
}
of_node_put(node_ctrl);
}
/* The clock setup for the 52xx works also fine for the 512x */
mpc_i2c_setup_52xx(node, i2c, clock, prescaler);
}
#else /* CONFIG_PPC_MPC512x */
static void __devinit mpc_i2c_setup_512x(struct device_node *node,
struct mpc_i2c *i2c, struct mpc_i2c *i2c,
u32 clock, u32 prescaler) u32 clock, u32 prescaler)
{ {
} }
#endif /* CONFIG_PPC_MPC52xx*/ #endif /* CONFIG_PPC_MPC512x */
#ifdef CONFIG_FSL_SOC #ifdef CONFIG_FSL_SOC
static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = { static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] __devinitconst = {
{160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123}, {160, 0x0120}, {192, 0x0121}, {224, 0x0122}, {256, 0x0123},
{288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102}, {288, 0x0100}, {320, 0x0101}, {352, 0x0601}, {384, 0x0102},
{416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127}, {416, 0x0602}, {448, 0x0126}, {480, 0x0103}, {512, 0x0127},
...@@ -258,7 +303,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = { ...@@ -258,7 +303,7 @@ static const struct mpc_i2c_divider mpc_i2c_dividers_8xxx[] = {
{49152, 0x011e}, {61440, 0x011f} {49152, 0x011e}, {61440, 0x011f}
}; };
u32 mpc_i2c_get_sec_cfg_8xxx(void) static u32 __devinit mpc_i2c_get_sec_cfg_8xxx(void)
{ {
struct device_node *node = NULL; struct device_node *node = NULL;
u32 __iomem *reg; u32 __iomem *reg;
...@@ -287,13 +332,14 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void) ...@@ -287,13 +332,14 @@ u32 mpc_i2c_get_sec_cfg_8xxx(void)
return val; return val;
} }
int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler) static int __devinit mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock,
u32 prescaler)
{ {
const struct mpc_i2c_divider *div = NULL; const struct mpc_i2c_divider *div = NULL;
u32 divider; u32 divider;
int i; int i;
if (!clock) if (clock == MPC_I2C_CLOCK_LEGACY)
return -EINVAL; return -EINVAL;
/* Determine proper divider value */ /* Determine proper divider value */
...@@ -320,12 +366,19 @@ int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler) ...@@ -320,12 +366,19 @@ int mpc_i2c_get_fdr_8xxx(struct device_node *node, u32 clock, u32 prescaler)
return div ? (int)div->fdr : -EINVAL; return div ? (int)div->fdr : -EINVAL;
} }
static void mpc_i2c_setclock_8xxx(struct device_node *node, static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
struct mpc_i2c *i2c, struct mpc_i2c *i2c,
u32 clock, u32 prescaler) u32 clock, u32 prescaler)
{ {
int ret, fdr; int ret, fdr;
if (clock == MPC_I2C_CLOCK_PRESERVE) {
dev_dbg(i2c->dev, "using dfsrr %d, fdr %d\n",
readb(i2c->base + MPC_I2C_DFSRR),
readb(i2c->base + MPC_I2C_FDR));
return;
}
ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler); ret = mpc_i2c_get_fdr_8xxx(node, clock, prescaler);
fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */ fdr = (ret >= 0) ? ret : 0x1031; /* backward compatibility */
...@@ -338,7 +391,7 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node, ...@@ -338,7 +391,7 @@ static void mpc_i2c_setclock_8xxx(struct device_node *node,
} }
#else /* !CONFIG_FSL_SOC */ #else /* !CONFIG_FSL_SOC */
static void mpc_i2c_setclock_8xxx(struct device_node *node, static void __devinit mpc_i2c_setup_8xxx(struct device_node *node,
struct mpc_i2c *i2c, struct mpc_i2c *i2c,
u32 clock, u32 prescaler) u32 clock, u32 prescaler)
{ {
...@@ -494,7 +547,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op, ...@@ -494,7 +547,7 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
{ {
struct mpc_i2c *i2c; struct mpc_i2c *i2c;
const u32 *prop; const u32 *prop;
u32 clock = 0; u32 clock = MPC_I2C_CLOCK_LEGACY;
int result = 0; int result = 0;
int plen; int plen;
...@@ -523,21 +576,21 @@ static int __devinit fsl_i2c_probe(struct of_device *op, ...@@ -523,21 +576,21 @@ static int __devinit fsl_i2c_probe(struct of_device *op,
} }
} }
if (!of_get_property(op->node, "fsl,preserve-clocking", NULL)) { if (of_get_property(op->node, "fsl,preserve-clocking", NULL)) {
clock = MPC_I2C_CLOCK_PRESERVE;
} else {
prop = of_get_property(op->node, "clock-frequency", &plen); prop = of_get_property(op->node, "clock-frequency", &plen);
if (prop && plen == sizeof(u32)) if (prop && plen == sizeof(u32))
clock = *prop; clock = *prop;
}
if (match->data) { if (match->data) {
struct mpc_i2c_match_data *data = struct mpc_i2c_data *data = match->data;
(struct mpc_i2c_match_data *)match->data; data->setup(op->node, i2c, clock, data->prescaler);
data->setclock(op->node, i2c, clock, data->prescaler);
} else { } else {
/* Backwards compatibility */ /* Backwards compatibility */
if (of_get_property(op->node, "dfsrr", NULL)) if (of_get_property(op->node, "dfsrr", NULL))
mpc_i2c_setclock_8xxx(op->node, i2c, mpc_i2c_setup_8xxx(op->node, i2c, clock, 0);
clock, 0);
}
} }
dev_set_drvdata(&op->dev, i2c); dev_set_drvdata(&op->dev, i2c);
...@@ -582,47 +635,42 @@ static int __devexit fsl_i2c_remove(struct of_device *op) ...@@ -582,47 +635,42 @@ static int __devexit fsl_i2c_remove(struct of_device *op)
return 0; return 0;
}; };
static const struct of_device_id mpc_i2c_of_match[] = { static struct mpc_i2c_data mpc_i2c_data_512x __devinitdata = {
{.compatible = "mpc5200-i2c", .setup = mpc_i2c_setup_512x,
.data = &(struct mpc_i2c_match_data) { };
.setclock = mpc_i2c_setclock_52xx,
}, static struct mpc_i2c_data mpc_i2c_data_52xx __devinitdata = {
}, .setup = mpc_i2c_setup_52xx,
{.compatible = "fsl,mpc5200b-i2c", };
.data = &(struct mpc_i2c_match_data) {
.setclock = mpc_i2c_setclock_52xx, static struct mpc_i2c_data mpc_i2c_data_8313 __devinitdata = {
}, .setup = mpc_i2c_setup_8xxx,
}, };
{.compatible = "fsl,mpc5200-i2c",
.data = &(struct mpc_i2c_match_data) { static struct mpc_i2c_data mpc_i2c_data_8543 __devinitdata = {
.setclock = mpc_i2c_setclock_52xx, .setup = mpc_i2c_setup_8xxx,
},
},
{.compatible = "fsl,mpc8313-i2c",
.data = &(struct mpc_i2c_match_data) {
.setclock = mpc_i2c_setclock_8xxx,
},
},
{.compatible = "fsl,mpc8543-i2c",
.data = &(struct mpc_i2c_match_data) {
.setclock = mpc_i2c_setclock_8xxx,
.prescaler = 2, .prescaler = 2,
}, };
},
{.compatible = "fsl,mpc8544-i2c", static struct mpc_i2c_data mpc_i2c_data_8544 __devinitdata = {
.data = &(struct mpc_i2c_match_data) { .setup = mpc_i2c_setup_8xxx,
.setclock = mpc_i2c_setclock_8xxx,
.prescaler = 3, .prescaler = 3,
}, };
static const struct of_device_id mpc_i2c_of_match[] = {
{.compatible = "mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
{.compatible = "fsl,mpc5200b-i2c", .data = &mpc_i2c_data_52xx, },
{.compatible = "fsl,mpc5200-i2c", .data = &mpc_i2c_data_52xx, },
{.compatible = "fsl,mpc5121-i2c", .data = &mpc_i2c_data_512x, },
{.compatible = "fsl,mpc8313-i2c", .data = &mpc_i2c_data_8313, },
{.compatible = "fsl,mpc8543-i2c", .data = &mpc_i2c_data_8543, },
{.compatible = "fsl,mpc8544-i2c", .data = &mpc_i2c_data_8544, },
/* Backward compatibility */ /* Backward compatibility */
},
{.compatible = "fsl-i2c", }, {.compatible = "fsl-i2c", },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, mpc_i2c_of_match); MODULE_DEVICE_TABLE(of, mpc_i2c_of_match);
/* Structure for a device driver */ /* Structure for a device driver */
static struct of_platform_driver mpc_i2c_driver = { static struct of_platform_driver mpc_i2c_driver = {
.match_table = mpc_i2c_of_match, .match_table = mpc_i2c_of_match,
...@@ -655,5 +703,5 @@ module_exit(fsl_i2c_exit); ...@@ -655,5 +703,5 @@ module_exit(fsl_i2c_exit);
MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>"); MODULE_AUTHOR("Adrian Cox <adrian@humboldt.co.uk>");
MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and " MODULE_DESCRIPTION("I2C-Bus adapter for MPC107 bridge and "
"MPC824x/85xx/52xx processors"); "MPC824x/83xx/85xx/86xx/512x/52xx processors");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
This diff is collapsed.
...@@ -49,24 +49,24 @@ ...@@ -49,24 +49,24 @@
#define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000)) #define OMAP_I2C_TIMEOUT (msecs_to_jiffies(1000))
#define OMAP_I2C_REV_REG 0x00 #define OMAP_I2C_REV_REG 0x00
#define OMAP_I2C_IE_REG 0x04 #define OMAP_I2C_IE_REG 0x01
#define OMAP_I2C_STAT_REG 0x08 #define OMAP_I2C_STAT_REG 0x02
#define OMAP_I2C_IV_REG 0x0c #define OMAP_I2C_IV_REG 0x03
/* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */ /* For OMAP3 I2C_IV has changed to I2C_WE (wakeup enable) */
#define OMAP_I2C_WE_REG 0x0c #define OMAP_I2C_WE_REG 0x03
#define OMAP_I2C_SYSS_REG 0x10 #define OMAP_I2C_SYSS_REG 0x04
#define OMAP_I2C_BUF_REG 0x14 #define OMAP_I2C_BUF_REG 0x05
#define OMAP_I2C_CNT_REG 0x18 #define OMAP_I2C_CNT_REG 0x06
#define OMAP_I2C_DATA_REG 0x1c #define OMAP_I2C_DATA_REG 0x07
#define OMAP_I2C_SYSC_REG 0x20 #define OMAP_I2C_SYSC_REG 0x08
#define OMAP_I2C_CON_REG 0x24 #define OMAP_I2C_CON_REG 0x09
#define OMAP_I2C_OA_REG 0x28 #define OMAP_I2C_OA_REG 0x0a
#define OMAP_I2C_SA_REG 0x2c #define OMAP_I2C_SA_REG 0x0b
#define OMAP_I2C_PSC_REG 0x30 #define OMAP_I2C_PSC_REG 0x0c
#define OMAP_I2C_SCLL_REG 0x34 #define OMAP_I2C_SCLL_REG 0x0d
#define OMAP_I2C_SCLH_REG 0x38 #define OMAP_I2C_SCLH_REG 0x0e
#define OMAP_I2C_SYSTEST_REG 0x3c #define OMAP_I2C_SYSTEST_REG 0x0f
#define OMAP_I2C_BUFSTAT_REG 0x40 #define OMAP_I2C_BUFSTAT_REG 0x10
/* I2C Interrupt Enable Register (OMAP_I2C_IE): */ /* I2C Interrupt Enable Register (OMAP_I2C_IE): */
#define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */ #define OMAP_I2C_IE_XDR (1 << 14) /* TX Buffer drain int enable */
...@@ -161,6 +161,7 @@ struct omap_i2c_dev { ...@@ -161,6 +161,7 @@ struct omap_i2c_dev {
struct device *dev; struct device *dev;
void __iomem *base; /* virtual */ void __iomem *base; /* virtual */
int irq; int irq;
int reg_shift; /* bit shift for I2C register addresses */
struct clk *iclk; /* Interface clock */ struct clk *iclk; /* Interface clock */
struct clk *fclk; /* Functional clock */ struct clk *fclk; /* Functional clock */
struct completion cmd_complete; struct completion cmd_complete;
...@@ -189,12 +190,12 @@ struct omap_i2c_dev { ...@@ -189,12 +190,12 @@ struct omap_i2c_dev {
static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev, static inline void omap_i2c_write_reg(struct omap_i2c_dev *i2c_dev,
int reg, u16 val) int reg, u16 val)
{ {
__raw_writew(val, i2c_dev->base + reg); __raw_writew(val, i2c_dev->base + (reg << i2c_dev->reg_shift));
} }
static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg) static inline u16 omap_i2c_read_reg(struct omap_i2c_dev *i2c_dev, int reg)
{ {
return __raw_readw(i2c_dev->base + reg); return __raw_readw(i2c_dev->base + (reg << i2c_dev->reg_shift));
} }
static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev) static int __init omap_i2c_get_clocks(struct omap_i2c_dev *dev)
...@@ -924,6 +925,11 @@ omap_i2c_probe(struct platform_device *pdev) ...@@ -924,6 +925,11 @@ omap_i2c_probe(struct platform_device *pdev)
dev->b_hw = 1; /* Enable hardware fixes */ dev->b_hw = 1; /* Enable hardware fixes */
} }
if (cpu_is_omap7xx())
dev->reg_shift = 1;
else
dev->reg_shift = 2;
/* reset ASAP, clearing any IRQs */ /* reset ASAP, clearing any IRQs */
omap_i2c_init(dev); omap_i2c_init(dev);
......
...@@ -172,12 +172,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data) ...@@ -172,12 +172,6 @@ static int i2c_pnx_master_xmit(struct i2c_pnx_algo_data *alg_data)
/* We still have something to talk about... */ /* We still have something to talk about... */
val = *alg_data->mif.buf++; val = *alg_data->mif.buf++;
if (alg_data->mif.len == 1) {
val |= stop_bit;
if (!alg_data->last)
val |= start_bit;
}
alg_data->mif.len--; alg_data->mif.len--;
iowrite32(val, I2C_REG_TX(alg_data)); iowrite32(val, I2C_REG_TX(alg_data));
...@@ -251,11 +245,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data) ...@@ -251,11 +245,6 @@ static int i2c_pnx_master_rcv(struct i2c_pnx_algo_data *alg_data)
__func__); __func__);
if (alg_data->mif.len == 1) { if (alg_data->mif.len == 1) {
/* Last byte, do not acknowledge next rcv. */
val |= stop_bit;
if (!alg_data->last)
val |= start_bit;
/* /*
* Enable interrupt RFDAIE (data in Rx fifo), * Enable interrupt RFDAIE (data in Rx fifo),
* and disable DRMIE (need data for Tx) * and disable DRMIE (need data for Tx)
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment