diff options
author | David Daney <ddaney@caviumnetworks.com> | 2010-01-07 13:23:41 -0800 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2010-02-27 12:53:04 +0100 |
commit | f41c3c1b3ed53440b37445712f8e1048a39d7001 (patch) | |
tree | c737d70385a32aea9de6a2d1e3b9a088c4bbe63f /arch/mips/cavium-octeon | |
parent | d38760ccdf879a8648be53488227bf7fe597792d (diff) |
MIPS: Octeon: Add I2C platform device.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
To: linux-mips@linux-mips.org
To: linux-i2c@vger.kernel.org
To: ben-linux@fluff.org
To: khali@linux-fr.org
Cc: Rade Bozic <rade.bozic.ext@nsn.com>
Patchwork: http://patchwork.linux-mips.org/patch/847/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
Diffstat (limited to 'arch/mips/cavium-octeon')
-rw-r--r-- | arch/mips/cavium-octeon/octeon-platform.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c index cfdb4c2ac5c..784c1c87401 100644 --- a/arch/mips/cavium-octeon/octeon-platform.c +++ b/arch/mips/cavium-octeon/octeon-platform.c @@ -159,6 +159,78 @@ out: } device_initcall(octeon_rng_device_init); + +#define OCTEON_I2C_IO_BASE 0x1180000001000ull +#define OCTEON_I2C_IO_UNIT_OFFSET 0x200 + +static struct octeon_i2c_data octeon_i2c_data[2]; + +static int __init octeon_i2c_device_init(void) +{ + struct platform_device *pd; + int ret = 0; + int port, num_ports; + + struct resource i2c_resources[] = { + { + .flags = IORESOURCE_MEM, + }, { + .flags = IORESOURCE_IRQ, + } + }; + + if (OCTEON_IS_MODEL(OCTEON_CN56XX) || OCTEON_IS_MODEL(OCTEON_CN52XX)) + num_ports = 2; + else + num_ports = 1; + + for (port = 0; port < num_ports; port++) { + octeon_i2c_data[port].sys_freq = octeon_get_clock_rate(); + /*FIXME: should be examined. At the moment is set for 100Khz */ + octeon_i2c_data[port].i2c_freq = 100000; + + pd = platform_device_alloc("i2c-octeon", port); + if (!pd) { + ret = -ENOMEM; + goto out; + } + + pd->dev.platform_data = octeon_i2c_data + port; + + i2c_resources[0].start = + OCTEON_I2C_IO_BASE + (port * OCTEON_I2C_IO_UNIT_OFFSET); + i2c_resources[0].end = i2c_resources[0].start + 0x1f; + switch (port) { + case 0: + i2c_resources[1].start = OCTEON_IRQ_TWSI; + i2c_resources[1].end = OCTEON_IRQ_TWSI; + break; + case 1: + i2c_resources[1].start = OCTEON_IRQ_TWSI2; + i2c_resources[1].end = OCTEON_IRQ_TWSI2; + break; + default: + BUG(); + } + + ret = platform_device_add_resources(pd, + i2c_resources, + ARRAY_SIZE(i2c_resources)); + if (ret) + goto fail; + + ret = platform_device_add(pd); + if (ret) + goto fail; + } + return ret; +fail: + platform_device_put(pd); +out: + return ret; +} +device_initcall(octeon_i2c_device_init); + /* Octeon SMI/MDIO interface. */ static int __init octeon_mdiobus_device_init(void) { |