i2c: designware: Add support for changing the bus rate based on DT info
authorLiviu Dudau <Liviu.Dudau@arm.com>
Fri, 3 Oct 2014 09:33:21 +0000 (10:33 +0100)
committerLiviu Dudau <Liviu.Dudau@arm.com>
Tue, 7 Oct 2014 11:11:02 +0000 (12:11 +0100)
The Designware I2C driver does not currently support changing the bus
speed even if the hardware is capable of switching to a slower frequency.
Add support for passing the clock frequency info in the device tree.
Only standard (100kHz) or fast (400kHz) speeds are supported.

Signed-off-by: Andrew Jackson <Andrew.Jackson@arm.com>
Signed-off-by: Liviu Dudau <Liviu.Dudau@arm.com>
drivers/i2c/busses/i2c-designware-platdrv.c

index 9c78026..bcec19f 100644 (file)
@@ -122,6 +122,7 @@ static int dw_i2c_probe(struct platform_device *pdev)
        struct i2c_adapter *adap;
        struct resource *mem;
        int irq, r;
+       u32 bus_rate = DW_IC_CON_SPEED_STD;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0) {
@@ -166,6 +167,22 @@ static int dw_i2c_probe(struct platform_device *pdev)
                of_property_read_u32(pdev->dev.of_node,
                                     "i2c-scl-falling-time-ns",
                                     &dev->scl_falling_time);
+
+               r = of_property_read_u32(pdev->dev.of_node, "clock-frequency",
+                                               &bus_rate);
+               if (r)
+                       bus_rate = 400000; /* default clock rate */
+               switch (bus_rate) {
+               case 400000:
+                       bus_rate = DW_IC_CON_SPEED_FAST;
+                       break;
+               case 100000:
+                       bus_rate = DW_IC_CON_SPEED_STD;
+                       break;
+               default:
+                       dev_err(&pdev->dev, "Invalid bus speed (not 100kHz or 400kHz)\n");
+                       return -EINVAL;
+               }
        }
 
        dev->functionality =
@@ -176,7 +193,7 @@ static int dw_i2c_probe(struct platform_device *pdev)
                I2C_FUNC_SMBUS_WORD_DATA |
                I2C_FUNC_SMBUS_I2C_BLOCK;
        dev->master_cfg =  DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
-               DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
+               DW_IC_CON_RESTART_EN | bus_rate;
 
        /* Try first if we can configure the device from ACPI */
        r = dw_i2c_acpi_configure(pdev);