diff options
Diffstat (limited to 'arch/arm/plat-omap/i2c.c')
| -rw-r--r-- | arch/arm/plat-omap/i2c.c | 172 |
1 files changed, 70 insertions, 102 deletions
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 7990ab185bb..58213d9714c 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -5,7 +5,7 @@ * * Copyright (C) 2007 Nokia Corporation. * - * Contact: Jarkko Nikula <jarkko.nikula@nokia.com> + * Contact: Jarkko Nikula <jhnikula@gmail.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -26,99 +26,80 @@ #include <linux/kernel.h> #include <linux/platform_device.h> #include <linux/i2c.h> -#include <asm/mach-types.h> -#include <asm/arch/mux.h> - -#define OMAP_I2C_SIZE 0x3f -#define OMAP1_I2C_BASE 0xfffb3800 -#define OMAP2_I2C_BASE1 0x48070000 -#define OMAP2_I2C_BASE2 0x48072000 -#define OMAP2_I2C_BASE3 0x48060000 - -static const char name[] = "i2c_omap"; - -#define I2C_RESOURCE_BUILDER(base, irq) \ - { \ - .start = (base), \ - .end = (base) + OMAP_I2C_SIZE, \ - .flags = IORESOURCE_MEM, \ - }, \ - { \ - .start = (irq), \ - .flags = IORESOURCE_IRQ, \ - }, - -static struct resource i2c_resources[][2] = { - { I2C_RESOURCE_BUILDER(0, 0) }, -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE2, INT_24XX_I2C2_IRQ) }, -#endif -#if defined(CONFIG_ARCH_OMAP34XX) - { I2C_RESOURCE_BUILDER(OMAP2_I2C_BASE3, INT_34XX_I2C3_IRQ) }, -#endif -}; - -#define I2C_DEV_BUILDER(bus_id, res, data) \ - { \ - .id = (bus_id), \ - .name = name, \ - .num_resources = ARRAY_SIZE(res), \ - .resource = (res), \ - .dev = { \ - .platform_data = (data), \ - }, \ - } +#include <linux/i2c-omap.h> +#include <linux/slab.h> +#include <linux/err.h> +#include <linux/clk.h> + +#include <plat/i2c.h> + +#define OMAP_I2C_MAX_CONTROLLERS 4 +static struct omap_i2c_bus_platform_data i2c_pdata[OMAP_I2C_MAX_CONTROLLERS]; + +#define OMAP_I2C_CMDLINE_SETUP (BIT(31)) -static u32 i2c_rate[ARRAY_SIZE(i2c_resources)]; -static struct platform_device omap_i2c_devices[] = { - I2C_DEV_BUILDER(1, i2c_resources[0], &i2c_rate[0]), -#if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX) - I2C_DEV_BUILDER(2, i2c_resources[1], &i2c_rate[1]), -#endif -#if defined(CONFIG_ARCH_OMAP34XX) - I2C_DEV_BUILDER(3, i2c_resources[2], &i2c_rate[2]), -#endif -}; - -static void __init omap_i2c_mux_pins(int bus_id) +/** + * omap_i2c_bus_setup - Process command line options for the I2C bus speed + * @str: String of options + * + * This function allow to override the default I2C bus speed for given I2C + * bus with a command line option. + * + * Format: i2c_bus=bus_id,clkrate (in kHz) + * + * Returns 1 on success, 0 otherwise. + */ +static int __init omap_i2c_bus_setup(char *str) { - /* TODO: Muxing for OMAP3 */ - switch (bus_id) { - case 1: - if (cpu_class_is_omap1()) { - omap_cfg_reg(I2C_SCL); - omap_cfg_reg(I2C_SDA); - } else if (cpu_is_omap24xx()) { - omap_cfg_reg(M19_24XX_I2C1_SCL); - omap_cfg_reg(L15_24XX_I2C1_SDA); - } - break; - case 2: - if (cpu_is_omap24xx()) { - omap_cfg_reg(J15_24XX_I2C2_SCL); - omap_cfg_reg(H19_24XX_I2C2_SDA); + int ints[3]; + + get_options(str, 3, ints); + if (ints[0] < 2 || ints[1] < 1 || + ints[1] > OMAP_I2C_MAX_CONTROLLERS) + return 0; + i2c_pdata[ints[1] - 1].clkrate = ints[2]; + i2c_pdata[ints[1] - 1].clkrate |= OMAP_I2C_CMDLINE_SETUP; + + return 1; +} +__setup("i2c_bus=", omap_i2c_bus_setup); + +/* + * Register busses defined in command line but that are not registered with + * omap_register_i2c_bus from board initialization code. + */ +int __init omap_register_i2c_bus_cmdline(void) +{ + int i, err = 0; + + for (i = 0; i < ARRAY_SIZE(i2c_pdata); i++) + if (i2c_pdata[i].clkrate & OMAP_I2C_CMDLINE_SETUP) { + i2c_pdata[i].clkrate &= ~OMAP_I2C_CMDLINE_SETUP; + err = omap_i2c_add_bus(&i2c_pdata[i], i + 1); + if (err) + goto out; } - break; - } + +out: + return err; } +/** + * omap_register_i2c_bus - register I2C bus with device descriptors + * @bus_id: bus id counting from number 1 + * @clkrate: clock rate of the bus in kHz + * @info: pointer into I2C device descriptor table or NULL + * @len: number of descriptors in the table + * + * Returns 0 on success or an error code. + */ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, struct i2c_board_info const *info, unsigned len) { - int ports, err; - struct platform_device *pdev; - struct resource *res; - resource_size_t base, irq; - - if (cpu_class_is_omap1()) - ports = 1; - else if (cpu_is_omap24xx()) - ports = 2; - else if (cpu_is_omap34xx()) - ports = 3; + int err; - BUG_ON(bus_id < 1 || bus_id > ports); + BUG_ON(bus_id < 1 || bus_id > OMAP_I2C_MAX_CONTROLLERS); if (info) { err = i2c_register_board_info(bus_id, info, len); @@ -126,23 +107,10 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, return err; } - pdev = &omap_i2c_devices[bus_id - 1]; - *(u32 *)pdev->dev.platform_data = clkrate; - - if (bus_id == 1) { - res = pdev->resource; - if (cpu_class_is_omap1()) { - base = OMAP1_I2C_BASE; - irq = INT_I2C; - } else { - base = OMAP2_I2C_BASE1; - irq = INT_24XX_I2C1_IRQ; - } - res[0].start = base; - res[0].end = base + OMAP_I2C_SIZE; - res[1].start = irq; - } + if (!i2c_pdata[bus_id - 1].clkrate) + i2c_pdata[bus_id - 1].clkrate = clkrate; + + i2c_pdata[bus_id - 1].clkrate &= ~OMAP_I2C_CMDLINE_SETUP; - omap_i2c_mux_pins(bus_id); - return platform_device_register(pdev); + return omap_i2c_add_bus(&i2c_pdata[bus_id - 1], bus_id); } |
