diff options
author | chin.yew.tan@intel.com <chin.yew.tan@intel.com> | 2017-03-28 04:48:02 -0400 |
---|---|---|
committer | Wolfram Sang <wsa@the-dreams.de> | 2017-04-19 14:54:21 -0400 |
commit | bd698d24b1b5790d0a22d44a0705dabd47235ad4 (patch) | |
tree | e1b48b9bc2e8485945b759b16a48ba015f94f8fc | |
parent | 2a03d49922fa2b89ceaa7d14b657c8a8e6bc7000 (diff) |
i2c: designware: Get selected speed mode sda-hold-time via ACPI
Sda-hold-time is an important parameter for tuning i2c to meet the
electrical specification especially for high speed. I2C with incorrect
sda-hold-time may cause lost arbitration error. Instead of loading all
speed mode settings, only selected speed mode settings are loaded.
Signed-off-by: Tan Chin Yew <chin.yew.tan@intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: Jarkko Nikula <jarkko.nikula@linux.intel.com>
Signed-off-by: Wolfram Sang <wsa@the-dreams.de>
-rw-r--r-- | drivers/i2c/busses/i2c-designware-platdrv.c | 31 |
1 files changed, 22 insertions, 9 deletions
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index a597ba32de7e..5a4eb6b6bd92 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c | |||
@@ -85,8 +85,7 @@ static void dw_i2c_acpi_params(struct platform_device *pdev, char method[], | |||
85 | 85 | ||
86 | *hcnt = (u16)objs[0].integer.value; | 86 | *hcnt = (u16)objs[0].integer.value; |
87 | *lcnt = (u16)objs[1].integer.value; | 87 | *lcnt = (u16)objs[1].integer.value; |
88 | if (sda_hold) | 88 | *sda_hold = (u32)objs[2].integer.value; |
89 | *sda_hold = (u32)objs[2].integer.value; | ||
90 | } | 89 | } |
91 | 90 | ||
92 | kfree(buf.pointer); | 91 | kfree(buf.pointer); |
@@ -105,14 +104,28 @@ static int dw_i2c_acpi_configure(struct platform_device *pdev) | |||
105 | dev->rx_fifo_depth = 32; | 104 | dev->rx_fifo_depth = 32; |
106 | 105 | ||
107 | /* | 106 | /* |
108 | * Try to get SDA hold time and *CNT values from an ACPI method if | 107 | * Try to get SDA hold time and *CNT values from an ACPI method for |
109 | * it exists for both supported speed modes. | 108 | * selected speed modes. |
110 | */ | 109 | */ |
111 | dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, NULL); | 110 | switch (dev->clk_freq) { |
112 | dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, | 111 | case 100000: |
113 | &dev->sda_hold_time); | 112 | dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, |
114 | dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, NULL); | 113 | &dev->sda_hold_time); |
115 | dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, NULL); | 114 | break; |
115 | case 1000000: | ||
116 | dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, | ||
117 | &dev->sda_hold_time); | ||
118 | break; | ||
119 | case 3400000: | ||
120 | dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, | ||
121 | &dev->sda_hold_time); | ||
122 | break; | ||
123 | case 400000: | ||
124 | default: | ||
125 | dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, | ||
126 | &dev->sda_hold_time); | ||
127 | break; | ||
128 | } | ||
116 | 129 | ||
117 | id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev); | 130 | id = acpi_match_device(pdev->dev.driver->acpi_match_table, &pdev->dev); |
118 | if (id && id->driver_data) | 131 | if (id && id->driver_data) |