diff options
Diffstat (limited to 'arch/arm/plat-omap/i2c.c')
-rw-r--r-- | arch/arm/plat-omap/i2c.c | 104 |
1 files changed, 89 insertions, 15 deletions
diff --git a/arch/arm/plat-omap/i2c.c b/arch/arm/plat-omap/i2c.c index 467531edefd3..a303071d5e36 100644 --- a/arch/arm/plat-omap/i2c.c +++ b/arch/arm/plat-omap/i2c.c @@ -98,6 +98,8 @@ static const int omap34xx_pins[][2] = { static const int omap34xx_pins[][2] = {}; #endif +#define OMAP_I2C_CMDLINE_SETUP (BIT(31)) + static void __init omap_i2c_mux_pins(int bus) { int scl, sda; @@ -119,14 +121,9 @@ static void __init omap_i2c_mux_pins(int bus) omap_cfg_reg(scl); } -int __init omap_register_i2c_bus(int bus_id, u32 clkrate, - struct i2c_board_info const *info, - unsigned len) +static int __init omap_i2c_nr_ports(void) { - int ports, err; - struct platform_device *pdev; - struct resource *res; - resource_size_t base, irq; + int ports = 0; if (cpu_class_is_omap1()) ports = 1; @@ -135,17 +132,16 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, else if (cpu_is_omap34xx()) ports = 3; - BUG_ON(bus_id < 1 || bus_id > ports); + return ports; +} - if (info) { - err = i2c_register_board_info(bus_id, info, len); - if (err) - return err; - } +static int __init omap_i2c_add_bus(int bus_id) +{ + struct platform_device *pdev; + struct resource *res; + resource_size_t base, irq; 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()) { @@ -163,3 +159,81 @@ int __init omap_register_i2c_bus(int bus_id, u32 clkrate, omap_i2c_mux_pins(bus_id - 1); return platform_device_register(pdev); } + +/** + * 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) +{ + int ports; + int ints[3]; + + ports = omap_i2c_nr_ports(); + get_options(str, 3, ints); + if (ints[0] < 2 || ints[1] < 1 || ints[1] > ports) + return 0; + i2c_rate[ints[1] - 1] = ints[2]; + i2c_rate[ints[1] - 1] |= 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. + */ +static int __init omap_register_i2c_bus_cmdline(void) +{ + int i, err = 0; + + for (i = 0; i < ARRAY_SIZE(i2c_rate); i++) + if (i2c_rate[i] & OMAP_I2C_CMDLINE_SETUP) { + i2c_rate[i] &= ~OMAP_I2C_CMDLINE_SETUP; + err = omap_i2c_add_bus(i + 1); + if (err) + goto out; + } + +out: + return err; +} +subsys_initcall(omap_register_i2c_bus_cmdline); + +/** + * 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 err; + + BUG_ON(bus_id < 1 || bus_id > omap_i2c_nr_ports()); + + if (info) { + err = i2c_register_board_info(bus_id, info, len); + if (err) + return err; + } + + if (!i2c_rate[bus_id - 1]) + i2c_rate[bus_id - 1] = clkrate; + i2c_rate[bus_id - 1] &= ~OMAP_I2C_CMDLINE_SETUP; + + return omap_i2c_add_bus(bus_id); +} |