Merge remote-tracking branch 'keys/keys-next'
[deliverable/linux.git] / drivers / i2c / busses / i2c-designware-platdrv.c
index d656657b805c20dafdfc28925c09179705789eae..0b42a12171f3a146ddc61ac6e2ed6d9d9cacf12e 100644 (file)
@@ -107,6 +107,8 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev)
        dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, NULL);
        dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
                           &dev->sda_hold_time);
+       dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, NULL);
+       dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, NULL);
 
        id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev);
        if (id && id->driver_data)
@@ -155,7 +157,7 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        struct i2c_adapter *adap;
        struct resource *mem;
        int irq, r;
-       u32 clk_freq, ht = 0;
+       u32 acpi_speed, ht = 0;
 
        irq = platform_get_irq(pdev, 0);
        if (irq < 0)
@@ -175,10 +177,10 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
        platform_set_drvdata(pdev, dev);
 
        /* fast mode by default because of legacy reasons */
-       clk_freq = 400000;
+       dev->clk_freq = 400000;
 
        if (pdata) {
-               clk_freq = pdata->i2c_scl_freq;
+               dev->clk_freq = pdata->i2c_scl_freq;
        } else {
                device_property_read_u32(&pdev->dev, "i2c-sda-hold-time-ns",
                                         &ht);
@@ -187,17 +189,24 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
                device_property_read_u32(&pdev->dev, "i2c-scl-falling-time-ns",
                                         &dev->scl_falling_time);
                device_property_read_u32(&pdev->dev, "clock-frequency",
-                                        &clk_freq);
+                                        &dev->clk_freq);
        }
 
+       acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
+       if (acpi_speed)
+               dev->clk_freq = acpi_speed;
+
        if (has_acpi_companion(&pdev->dev))
                dw_i2c_acpi_configure(pdev);
 
        /*
-        * Only standard mode at 100kHz and fast mode at 400kHz are supported.
+        * Only standard mode at 100kHz, fast mode at 400kHz,
+        * fast mode plus at 1MHz and high speed mode at 3.4MHz are supported.
         */
-       if (clk_freq != 100000 && clk_freq != 400000) {
-               dev_err(&pdev->dev, "Only 100kHz and 400kHz supported");
+       if (dev->clk_freq != 100000 && dev->clk_freq != 400000
+           && dev->clk_freq != 1000000 && dev->clk_freq != 3400000) {
+               dev_err(&pdev->dev,
+                       "Only 100kHz, 400kHz, 1MHz and 3.4MHz supported");
                return -EINVAL;
        }
 
@@ -212,12 +221,20 @@ static int dw_i2c_plat_probe(struct platform_device *pdev)
                I2C_FUNC_SMBUS_BYTE_DATA |
                I2C_FUNC_SMBUS_WORD_DATA |
                I2C_FUNC_SMBUS_I2C_BLOCK;
-       if (clk_freq == 100000)
-               dev->master_cfg =  DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
-                       DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_STD;
-       else
-               dev->master_cfg =  DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
-                       DW_IC_CON_RESTART_EN | DW_IC_CON_SPEED_FAST;
+
+       dev->master_cfg = DW_IC_CON_MASTER | DW_IC_CON_SLAVE_DISABLE |
+                         DW_IC_CON_RESTART_EN;
+
+       switch (dev->clk_freq) {
+       case 100000:
+               dev->master_cfg |= DW_IC_CON_SPEED_STD;
+               break;
+       case 3400000:
+               dev->master_cfg |= DW_IC_CON_SPEED_HIGH;
+               break;
+       default:
+               dev->master_cfg |= DW_IC_CON_SPEED_FAST;
+       }
 
        dev->clk = devm_clk_get(&pdev->dev, NULL);
        if (!i2c_dw_plat_prepare_clk(dev, true)) {
This page took 0.027151 seconds and 5 git commands to generate.