summary refs log tree commit diff
path: root/arch/arm/plat-omap/i2c.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/plat-omap/i2c.c')
-rw-r--r--arch/arm/plat-omap/i2c.c104
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);
+}