0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #include <linux/acpi.h>
0012 #include <linux/clk-provider.h>
0013 #include <linux/clk.h>
0014 #include <linux/delay.h>
0015 #include <linux/dmi.h>
0016 #include <linux/err.h>
0017 #include <linux/errno.h>
0018 #include <linux/i2c.h>
0019 #include <linux/interrupt.h>
0020 #include <linux/io.h>
0021 #include <linux/kernel.h>
0022 #include <linux/mfd/syscon.h>
0023 #include <linux/module.h>
0024 #include <linux/of.h>
0025 #include <linux/platform_device.h>
0026 #include <linux/pm.h>
0027 #include <linux/pm_runtime.h>
0028 #include <linux/property.h>
0029 #include <linux/regmap.h>
0030 #include <linux/reset.h>
0031 #include <linux/sched.h>
0032 #include <linux/slab.h>
0033 #include <linux/suspend.h>
0034 #include <linux/units.h>
0035
0036 #include "i2c-designware-core.h"
0037
0038 static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
0039 {
0040 return clk_get_rate(dev->clk) / KILO;
0041 }
0042
0043 #ifdef CONFIG_ACPI
0044 static const struct acpi_device_id dw_i2c_acpi_match[] = {
0045 { "INT33C2", 0 },
0046 { "INT33C3", 0 },
0047 { "INT3432", 0 },
0048 { "INT3433", 0 },
0049 { "80860F41", ACCESS_NO_IRQ_SUSPEND },
0050 { "808622C1", ACCESS_NO_IRQ_SUSPEND },
0051 { "AMD0010", ACCESS_INTR_MASK },
0052 { "AMDI0010", ACCESS_INTR_MASK },
0053 { "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE },
0054 { "AMDI0510", 0 },
0055 { "APMC0D0F", 0 },
0056 { "HISI02A1", 0 },
0057 { "HISI02A2", 0 },
0058 { "HISI02A3", 0 },
0059 { "HYGO0010", ACCESS_INTR_MASK },
0060 { }
0061 };
0062 MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
0063 #endif
0064
0065 #ifdef CONFIG_OF
0066 #define BT1_I2C_CTL 0x100
0067 #define BT1_I2C_CTL_ADDR_MASK GENMASK(7, 0)
0068 #define BT1_I2C_CTL_WR BIT(8)
0069 #define BT1_I2C_CTL_GO BIT(31)
0070 #define BT1_I2C_DI 0x104
0071 #define BT1_I2C_DO 0x108
0072
0073 static int bt1_i2c_read(void *context, unsigned int reg, unsigned int *val)
0074 {
0075 struct dw_i2c_dev *dev = context;
0076 int ret;
0077
0078
0079
0080
0081
0082 ret = regmap_write(dev->sysmap, BT1_I2C_CTL,
0083 BT1_I2C_CTL_GO | (reg & BT1_I2C_CTL_ADDR_MASK));
0084 if (ret)
0085 return ret;
0086
0087 return regmap_read(dev->sysmap, BT1_I2C_DO, val);
0088 }
0089
0090 static int bt1_i2c_write(void *context, unsigned int reg, unsigned int val)
0091 {
0092 struct dw_i2c_dev *dev = context;
0093 int ret;
0094
0095 ret = regmap_write(dev->sysmap, BT1_I2C_DI, val);
0096 if (ret)
0097 return ret;
0098
0099 return regmap_write(dev->sysmap, BT1_I2C_CTL,
0100 BT1_I2C_CTL_GO | BT1_I2C_CTL_WR | (reg & BT1_I2C_CTL_ADDR_MASK));
0101 }
0102
0103 static struct regmap_config bt1_i2c_cfg = {
0104 .reg_bits = 32,
0105 .val_bits = 32,
0106 .reg_stride = 4,
0107 .fast_io = true,
0108 .reg_read = bt1_i2c_read,
0109 .reg_write = bt1_i2c_write,
0110 .max_register = DW_IC_COMP_TYPE,
0111 };
0112
0113 static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
0114 {
0115 dev->sysmap = syscon_node_to_regmap(dev->dev->of_node->parent);
0116 if (IS_ERR(dev->sysmap))
0117 return PTR_ERR(dev->sysmap);
0118
0119 dev->map = devm_regmap_init(dev->dev, NULL, dev, &bt1_i2c_cfg);
0120 return PTR_ERR_OR_ZERO(dev->map);
0121 }
0122
0123 #define MSCC_ICPU_CFG_TWI_DELAY 0x0
0124 #define MSCC_ICPU_CFG_TWI_DELAY_ENABLE BIT(0)
0125 #define MSCC_ICPU_CFG_TWI_SPIKE_FILTER 0x4
0126
0127 static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
0128 {
0129 writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE,
0130 dev->ext + MSCC_ICPU_CFG_TWI_DELAY);
0131
0132 return 0;
0133 }
0134
0135 static int dw_i2c_of_configure(struct platform_device *pdev)
0136 {
0137 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
0138
0139 switch (dev->flags & MODEL_MASK) {
0140 case MODEL_MSCC_OCELOT:
0141 dev->ext = devm_platform_ioremap_resource(pdev, 1);
0142 if (!IS_ERR(dev->ext))
0143 dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
0144 break;
0145 default:
0146 break;
0147 }
0148
0149 return 0;
0150 }
0151
0152 static const struct of_device_id dw_i2c_of_match[] = {
0153 { .compatible = "snps,designware-i2c", },
0154 { .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT },
0155 { .compatible = "baikal,bt1-sys-i2c", .data = (void *)MODEL_BAIKAL_BT1 },
0156 {},
0157 };
0158 MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
0159 #else
0160 static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
0161 {
0162 return -ENODEV;
0163 }
0164
0165 static inline int dw_i2c_of_configure(struct platform_device *pdev)
0166 {
0167 return -ENODEV;
0168 }
0169 #endif
0170
0171 static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
0172 {
0173 pm_runtime_disable(dev->dev);
0174
0175 if (dev->shared_with_punit)
0176 pm_runtime_put_noidle(dev->dev);
0177 }
0178
0179 static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev)
0180 {
0181 struct platform_device *pdev = to_platform_device(dev->dev);
0182 int ret;
0183
0184 switch (dev->flags & MODEL_MASK) {
0185 case MODEL_BAIKAL_BT1:
0186 ret = bt1_i2c_request_regs(dev);
0187 break;
0188 default:
0189 dev->base = devm_platform_ioremap_resource(pdev, 0);
0190 ret = PTR_ERR_OR_ZERO(dev->base);
0191 break;
0192 }
0193
0194 return ret;
0195 }
0196
0197 static const struct dmi_system_id dw_i2c_hwmon_class_dmi[] = {
0198 {
0199 .ident = "Qtechnology QT5222",
0200 .matches = {
0201 DMI_MATCH(DMI_SYS_VENDOR, "Qtechnology"),
0202 DMI_MATCH(DMI_PRODUCT_NAME, "QT5222"),
0203 },
0204 },
0205 { }
0206 };
0207
0208 static const struct i2c_dw_semaphore_callbacks i2c_dw_semaphore_cb_table[] = {
0209 #ifdef CONFIG_I2C_DESIGNWARE_BAYTRAIL
0210 {
0211 .probe = i2c_dw_baytrail_probe_lock_support,
0212 },
0213 #endif
0214 #ifdef CONFIG_I2C_DESIGNWARE_AMDPSP
0215 {
0216 .probe = i2c_dw_amdpsp_probe_lock_support,
0217 .remove = i2c_dw_amdpsp_remove_lock_support,
0218 },
0219 #endif
0220 {}
0221 };
0222
0223 static int i2c_dw_probe_lock_support(struct dw_i2c_dev *dev)
0224 {
0225 const struct i2c_dw_semaphore_callbacks *ptr;
0226 int i = 0;
0227 int ret;
0228
0229 ptr = i2c_dw_semaphore_cb_table;
0230
0231 dev->semaphore_idx = -1;
0232
0233 while (ptr->probe) {
0234 ret = ptr->probe(dev);
0235 if (ret) {
0236
0237
0238
0239
0240
0241 if (ret != -ENODEV)
0242 return ret;
0243
0244 i++;
0245 ptr++;
0246 continue;
0247 }
0248
0249 dev->semaphore_idx = i;
0250 break;
0251 }
0252
0253 return 0;
0254 }
0255
0256 static void i2c_dw_remove_lock_support(struct dw_i2c_dev *dev)
0257 {
0258 if (dev->semaphore_idx < 0)
0259 return;
0260
0261 if (i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove)
0262 i2c_dw_semaphore_cb_table[dev->semaphore_idx].remove(dev);
0263 }
0264
0265 static int dw_i2c_plat_probe(struct platform_device *pdev)
0266 {
0267 struct i2c_adapter *adap;
0268 struct dw_i2c_dev *dev;
0269 struct i2c_timings *t;
0270 int irq, ret;
0271
0272 irq = platform_get_irq(pdev, 0);
0273 if (irq < 0)
0274 return irq;
0275
0276 dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL);
0277 if (!dev)
0278 return -ENOMEM;
0279
0280 dev->flags = (uintptr_t)device_get_match_data(&pdev->dev);
0281 dev->dev = &pdev->dev;
0282 dev->irq = irq;
0283 platform_set_drvdata(pdev, dev);
0284
0285 ret = dw_i2c_plat_request_regs(dev);
0286 if (ret)
0287 return ret;
0288
0289 dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
0290 if (IS_ERR(dev->rst))
0291 return PTR_ERR(dev->rst);
0292
0293 reset_control_deassert(dev->rst);
0294
0295 t = &dev->timings;
0296 i2c_parse_fw_timings(&pdev->dev, t, false);
0297
0298 i2c_dw_adjust_bus_speed(dev);
0299
0300 if (pdev->dev.of_node)
0301 dw_i2c_of_configure(pdev);
0302
0303 if (has_acpi_companion(&pdev->dev))
0304 i2c_dw_acpi_configure(&pdev->dev);
0305
0306 ret = i2c_dw_validate_speed(dev);
0307 if (ret)
0308 goto exit_reset;
0309
0310 ret = i2c_dw_probe_lock_support(dev);
0311 if (ret)
0312 goto exit_reset;
0313
0314 i2c_dw_configure(dev);
0315
0316
0317 dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
0318 if (IS_ERR(dev->pclk)) {
0319 ret = PTR_ERR(dev->pclk);
0320 goto exit_reset;
0321 }
0322
0323 dev->clk = devm_clk_get_optional(&pdev->dev, NULL);
0324 if (IS_ERR(dev->clk)) {
0325 ret = PTR_ERR(dev->clk);
0326 goto exit_reset;
0327 }
0328
0329 ret = i2c_dw_prepare_clk(dev, true);
0330 if (ret)
0331 goto exit_reset;
0332
0333 if (dev->clk) {
0334 u64 clk_khz;
0335
0336 dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
0337 clk_khz = dev->get_clk_rate_khz(dev);
0338
0339 if (!dev->sda_hold_time && t->sda_hold_ns)
0340 dev->sda_hold_time =
0341 DIV_S64_ROUND_CLOSEST(clk_khz * t->sda_hold_ns, MICRO);
0342 }
0343
0344 adap = &dev->adapter;
0345 adap->owner = THIS_MODULE;
0346 adap->class = dmi_check_system(dw_i2c_hwmon_class_dmi) ?
0347 I2C_CLASS_HWMON : I2C_CLASS_DEPRECATED;
0348 ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev));
0349 adap->dev.of_node = pdev->dev.of_node;
0350 adap->nr = -1;
0351
0352 if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
0353 dev_pm_set_driver_flags(&pdev->dev,
0354 DPM_FLAG_SMART_PREPARE |
0355 DPM_FLAG_MAY_SKIP_RESUME);
0356 } else {
0357 dev_pm_set_driver_flags(&pdev->dev,
0358 DPM_FLAG_SMART_PREPARE |
0359 DPM_FLAG_SMART_SUSPEND |
0360 DPM_FLAG_MAY_SKIP_RESUME);
0361 }
0362
0363 device_enable_async_suspend(&pdev->dev);
0364
0365
0366 WARN_ON(pm_runtime_enabled(&pdev->dev));
0367
0368 pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
0369 pm_runtime_use_autosuspend(&pdev->dev);
0370 pm_runtime_set_active(&pdev->dev);
0371
0372 if (dev->shared_with_punit)
0373 pm_runtime_get_noresume(&pdev->dev);
0374
0375 pm_runtime_enable(&pdev->dev);
0376
0377 ret = i2c_dw_probe(dev);
0378 if (ret)
0379 goto exit_probe;
0380
0381 return ret;
0382
0383 exit_probe:
0384 dw_i2c_plat_pm_cleanup(dev);
0385 exit_reset:
0386 reset_control_assert(dev->rst);
0387 return ret;
0388 }
0389
0390 static int dw_i2c_plat_remove(struct platform_device *pdev)
0391 {
0392 struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
0393
0394 pm_runtime_get_sync(&pdev->dev);
0395
0396 i2c_del_adapter(&dev->adapter);
0397
0398 dev->disable(dev);
0399
0400 pm_runtime_dont_use_autosuspend(&pdev->dev);
0401 pm_runtime_put_sync(&pdev->dev);
0402 dw_i2c_plat_pm_cleanup(dev);
0403
0404 i2c_dw_remove_lock_support(dev);
0405
0406 reset_control_assert(dev->rst);
0407
0408 return 0;
0409 }
0410
0411 #ifdef CONFIG_PM_SLEEP
0412 static int dw_i2c_plat_prepare(struct device *dev)
0413 {
0414
0415
0416
0417
0418
0419
0420 return !has_acpi_companion(dev);
0421 }
0422
0423 static void dw_i2c_plat_complete(struct device *dev)
0424 {
0425
0426
0427
0428
0429
0430
0431 if (pm_runtime_suspended(dev) && pm_resume_via_firmware())
0432 pm_request_resume(dev);
0433 }
0434 #else
0435 #define dw_i2c_plat_prepare NULL
0436 #define dw_i2c_plat_complete NULL
0437 #endif
0438
0439 #ifdef CONFIG_PM
0440 static int dw_i2c_plat_runtime_suspend(struct device *dev)
0441 {
0442 struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
0443
0444 if (i_dev->shared_with_punit)
0445 return 0;
0446
0447 i_dev->disable(i_dev);
0448 i2c_dw_prepare_clk(i_dev, false);
0449
0450 return 0;
0451 }
0452
0453 static int __maybe_unused dw_i2c_plat_suspend(struct device *dev)
0454 {
0455 struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
0456
0457 i2c_mark_adapter_suspended(&i_dev->adapter);
0458
0459 return dw_i2c_plat_runtime_suspend(dev);
0460 }
0461
0462 static int dw_i2c_plat_runtime_resume(struct device *dev)
0463 {
0464 struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
0465
0466 if (!i_dev->shared_with_punit)
0467 i2c_dw_prepare_clk(i_dev, true);
0468
0469 i_dev->init(i_dev);
0470
0471 return 0;
0472 }
0473
0474 static int __maybe_unused dw_i2c_plat_resume(struct device *dev)
0475 {
0476 struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
0477
0478 dw_i2c_plat_runtime_resume(dev);
0479 i2c_mark_adapter_resumed(&i_dev->adapter);
0480
0481 return 0;
0482 }
0483
0484 static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
0485 .prepare = dw_i2c_plat_prepare,
0486 .complete = dw_i2c_plat_complete,
0487 SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
0488 SET_RUNTIME_PM_OPS(dw_i2c_plat_runtime_suspend, dw_i2c_plat_runtime_resume, NULL)
0489 };
0490
0491 #define DW_I2C_DEV_PMOPS (&dw_i2c_dev_pm_ops)
0492 #else
0493 #define DW_I2C_DEV_PMOPS NULL
0494 #endif
0495
0496
0497 MODULE_ALIAS("platform:i2c_designware");
0498
0499 static struct platform_driver dw_i2c_driver = {
0500 .probe = dw_i2c_plat_probe,
0501 .remove = dw_i2c_plat_remove,
0502 .driver = {
0503 .name = "i2c_designware",
0504 .of_match_table = of_match_ptr(dw_i2c_of_match),
0505 .acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
0506 .pm = DW_I2C_DEV_PMOPS,
0507 },
0508 };
0509
0510 static int __init dw_i2c_init_driver(void)
0511 {
0512 return platform_driver_register(&dw_i2c_driver);
0513 }
0514 subsys_initcall(dw_i2c_init_driver);
0515
0516 static void __exit dw_i2c_exit_driver(void)
0517 {
0518 platform_driver_unregister(&dw_i2c_driver);
0519 }
0520 module_exit(dw_i2c_exit_driver);
0521
0522 MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
0523 MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter");
0524 MODULE_LICENSE("GPL");