i2c-designware-platdrv.c 10.9 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
 * Synopsys DesignWare I2C adapter driver.
4 5 6 7 8 9 10
 *
 * Based on the TI DAVINCI I2C adapter driver.
 *
 * Copyright (C) 2006 Texas Instruments.
 * Copyright (C) 2007 MontaVista Software Inc.
 * Copyright (C) 2009 Provigent Ltd.
 */
11 12 13
#include <linux/acpi.h>
#include <linux/clk-provider.h>
#include <linux/clk.h>
14
#include <linux/delay.h>
15
#include <linux/dmi.h>
16
#include <linux/err.h>
17 18
#include <linux/errno.h>
#include <linux/i2c.h>
19
#include <linux/interrupt.h>
20 21 22
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
23
#include <linux/of.h>
24
#include <linux/platform_data/i2c-designware.h>
25
#include <linux/platform_device.h>
D
Deepak Sikri 已提交
26
#include <linux/pm.h>
27
#include <linux/pm_runtime.h>
28
#include <linux/property.h>
29
#include <linux/reset.h>
30
#include <linux/sched.h>
31
#include <linux/slab.h>
32
#include <linux/suspend.h>
33

34 35
#include "i2c-designware-core.h"

36 37 38 39
static u32 i2c_dw_get_clk_rate_khz(struct dw_i2c_dev *dev)
{
	return clk_get_rate(dev->clk)/1000;
}
40

41
#ifdef CONFIG_ACPI
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
/*
 * The HCNT/LCNT information coming from ACPI should be the most accurate
 * for given platform. However, some systems get it wrong. On such systems
 * we get better results by calculating those based on the input clock.
 */
static const struct dmi_system_id dw_i2c_no_acpi_params[] = {
	{
		.ident = "Dell Inspiron 7348",
		.matches = {
			DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."),
			DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7348"),
		},
	},
	{ }
};

58 59 60 61 62 63 64
static void dw_i2c_acpi_params(struct platform_device *pdev, char method[],
			       u16 *hcnt, u16 *lcnt, u32 *sda_hold)
{
	struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER };
	acpi_handle handle = ACPI_HANDLE(&pdev->dev);
	union acpi_object *obj;

65 66 67
	if (dmi_check_system(dw_i2c_no_acpi_params))
		return;

68 69 70 71 72 73 74 75 76
	if (ACPI_FAILURE(acpi_evaluate_object(handle, method, NULL, &buf)))
		return;

	obj = (union acpi_object *)buf.pointer;
	if (obj->type == ACPI_TYPE_PACKAGE && obj->package.count == 3) {
		const union acpi_object *objs = obj->package.elements;

		*hcnt = (u16)objs[0].integer.value;
		*lcnt = (u16)objs[1].integer.value;
77
		*sda_hold = (u32)objs[2].integer.value;
78 79 80 81 82
	}

	kfree(buf.pointer);
}

83 84 85
static int dw_i2c_acpi_configure(struct platform_device *pdev)
{
	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);
86
	struct i2c_timings *t = &dev->timings;
87
	u32 ss_ht = 0, fp_ht = 0, hs_ht = 0, fs_ht = 0;
88 89 90

	dev->tx_fifo_depth = 32;
	dev->rx_fifo_depth = 32;
91 92

	/*
93 94
	 * Try to get SDA hold time and *CNT values from an ACPI method for
	 * selected speed modes.
95
	 */
96 97 98 99 100
	dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, &ss_ht);
	dw_i2c_acpi_params(pdev, "FPCN", &dev->fp_hcnt, &dev->fp_lcnt, &fp_ht);
	dw_i2c_acpi_params(pdev, "HSCN", &dev->hs_hcnt, &dev->hs_lcnt, &hs_ht);
	dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt, &fs_ht);

101
	switch (t->bus_freq_hz) {
102
	case I2C_MAX_STANDARD_MODE_FREQ:
103
		dev->sda_hold_time = ss_ht;
104
		break;
105
	case I2C_MAX_FAST_MODE_PLUS_FREQ:
106
		dev->sda_hold_time = fp_ht;
107
		break;
108
	case I2C_MAX_HIGH_SPEED_MODE_FREQ:
109
		dev->sda_hold_time = hs_ht;
110
		break;
111
	case I2C_MAX_FAST_MODE_FREQ:
112
	default:
113
		dev->sda_hold_time = fs_ht;
114 115
		break;
	}
116

117 118 119 120 121 122
	return 0;
}

static const struct acpi_device_id dw_i2c_acpi_match[] = {
	{ "INT33C2", 0 },
	{ "INT33C3", 0 },
123 124
	{ "INT3432", 0 },
	{ "INT3433", 0 },
125 126
	{ "80860F41", ACCESS_NO_IRQ_SUSPEND },
	{ "808622C1", ACCESS_NO_IRQ_SUSPEND | MODEL_CHERRYTRAIL },
127
	{ "AMD0010", ACCESS_INTR_MASK },
128
	{ "AMDI0010", ACCESS_INTR_MASK },
129
	{ "AMDI0510", 0 },
130
	{ "APMC0D0F", 0 },
131 132
	{ "HISI02A1", 0 },
	{ "HISI02A2", 0 },
133
	{ "HISI02A3", 0 },
134 135 136 137 138 139 140 141 142 143
	{ }
};
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
#else
static inline int dw_i2c_acpi_configure(struct platform_device *pdev)
{
	return -ENODEV;
}
#endif

144
#ifdef CONFIG_OF
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
#define MSCC_ICPU_CFG_TWI_DELAY		0x0
#define MSCC_ICPU_CFG_TWI_DELAY_ENABLE	BIT(0)
#define MSCC_ICPU_CFG_TWI_SPIKE_FILTER	0x4

static int mscc_twi_set_sda_hold_time(struct dw_i2c_dev *dev)
{
	writel((dev->sda_hold_time << 1) | MSCC_ICPU_CFG_TWI_DELAY_ENABLE,
	       dev->ext + MSCC_ICPU_CFG_TWI_DELAY);

	return 0;
}

static int dw_i2c_of_configure(struct platform_device *pdev)
{
	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);

	switch (dev->flags & MODEL_MASK) {
	case MODEL_MSCC_OCELOT:
163
		dev->ext = devm_platform_ioremap_resource(pdev, 1);
164 165 166 167 168 169 170 171 172 173
		if (!IS_ERR(dev->ext))
			dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
		break;
	default:
		break;
	}

	return 0;
}

174 175
static const struct of_device_id dw_i2c_of_match[] = {
	{ .compatible = "snps,designware-i2c", },
176
	{ .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT },
177 178 179
	{},
};
MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
180 181 182 183 184
#else
static inline int dw_i2c_of_configure(struct platform_device *pdev)
{
	return -ENODEV;
}
185 186
#endif

187 188 189 190
static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
{
	pm_runtime_disable(dev->dev);

191
	if (dev->shared_with_punit)
192 193 194
		pm_runtime_put_noidle(dev->dev);
}

195
static int dw_i2c_plat_probe(struct platform_device *pdev)
196
{
197
	struct dw_i2c_platform_data *pdata = dev_get_platdata(&pdev->dev);
198
	struct i2c_adapter *adap;
199
	struct dw_i2c_dev *dev;
200 201
	struct i2c_timings *t;
	u32 acpi_speed;
202
	int i, irq, ret;
203 204

	irq = platform_get_irq(pdev, 0);
205 206
	if (irq < 0)
		return irq;
207

208 209 210
	dev = devm_kzalloc(&pdev->dev, sizeof(struct dw_i2c_dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;
211

212
	dev->base = devm_platform_ioremap_resource(pdev, 0);
213 214
	if (IS_ERR(dev->base))
		return PTR_ERR(dev->base);
215

216
	dev->dev = &pdev->dev;
217 218 219
	dev->irq = irq;
	platform_set_drvdata(pdev, dev);

220
	dev->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL);
221 222 223 224
	if (IS_ERR(dev->rst))
		return PTR_ERR(dev->rst);

	reset_control_deassert(dev->rst);
225

226 227 228 229 230
	t = &dev->timings;
	if (pdata)
		t->bus_freq_hz = pdata->i2c_scl_freq;
	else
		i2c_parse_fw_timings(&pdev->dev, t, false);
231

232
	acpi_speed = i2c_acpi_find_bus_speed(&pdev->dev);
233 234 235 236
	/*
	 * Some DSTDs use a non standard speed, round down to the lowest
	 * standard speed.
	 */
237 238
	for (i = 0; i < ARRAY_SIZE(i2c_dw_supported_speeds); i++) {
		if (acpi_speed >= i2c_dw_supported_speeds[i])
239 240
			break;
	}
241
	acpi_speed = i < ARRAY_SIZE(i2c_dw_supported_speeds) ? i2c_dw_supported_speeds[i] : 0;
242

243 244 245 246
	/*
	 * Find bus speed from the "clock-frequency" device property, ACPI
	 * or by using fast mode if neither is set.
	 */
247 248 249 250
	if (acpi_speed && t->bus_freq_hz)
		t->bus_freq_hz = min(t->bus_freq_hz, acpi_speed);
	else if (acpi_speed || t->bus_freq_hz)
		t->bus_freq_hz = max(t->bus_freq_hz, acpi_speed);
251
	else
252
		t->bus_freq_hz = I2C_MAX_FAST_MODE_FREQ;
253

254 255
	dev->flags |= (uintptr_t)device_get_match_data(&pdev->dev);

256 257 258
	if (pdev->dev.of_node)
		dw_i2c_of_configure(pdev);

259 260 261
	if (has_acpi_companion(&pdev->dev))
		dw_i2c_acpi_configure(pdev);

262 263
	ret = i2c_dw_validate_speed(dev);
	if (ret)
264
		goto exit_reset;
265

266 267
	ret = i2c_dw_probe_lock_support(dev);
	if (ret)
268
		goto exit_reset;
269

270
	i2c_dw_configure(dev);
271

272 273
	/* Optional interface clock */
	dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
274 275 276 277
	if (IS_ERR(dev->pclk)) {
		ret = PTR_ERR(dev->pclk);
		goto exit_reset;
	}
278

279
	dev->clk = devm_clk_get(&pdev->dev, NULL);
280
	if (!i2c_dw_prepare_clk(dev, true)) {
281 282
		u64 clk_khz;

283
		dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
284
		clk_khz = dev->get_clk_rate_khz(dev);
285

286 287 288
		if (!dev->sda_hold_time && t->sda_hold_ns)
			dev->sda_hold_time =
				div_u64(clk_khz * t->sda_hold_ns + 500000, 1000000);
289 290
	}

291 292
	adap = &dev->adapter;
	adap->owner = THIS_MODULE;
293
	adap->class = I2C_CLASS_DEPRECATED;
294
	ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev));
295
	adap->dev.of_node = pdev->dev.of_node;
296
	adap->nr = -1;
297

298 299 300 301 302 303 304 305 306 307
	if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
		dev_pm_set_driver_flags(&pdev->dev,
					DPM_FLAG_SMART_PREPARE |
					DPM_FLAG_LEAVE_SUSPENDED);
	} else {
		dev_pm_set_driver_flags(&pdev->dev,
					DPM_FLAG_SMART_PREPARE |
					DPM_FLAG_SMART_SUSPEND |
					DPM_FLAG_LEAVE_SUSPENDED);
	}
308

309 310 311 312 313 314 315
	/* The code below assumes runtime PM to be disabled. */
	WARN_ON(pm_runtime_enabled(&pdev->dev));

	pm_runtime_set_autosuspend_delay(&pdev->dev, 1000);
	pm_runtime_use_autosuspend(&pdev->dev);
	pm_runtime_set_active(&pdev->dev);

316
	if (dev->shared_with_punit)
317 318 319
		pm_runtime_get_noresume(&pdev->dev);

	pm_runtime_enable(&pdev->dev);
320

321
	ret = i2c_dw_probe(dev);
322
	if (ret)
323
		goto exit_probe;
324

325
	return ret;
326 327

exit_probe:
328
	dw_i2c_plat_pm_cleanup(dev);
329
exit_reset:
330
	reset_control_assert(dev->rst);
331
	return ret;
332 333
}

334
static int dw_i2c_plat_remove(struct platform_device *pdev)
335 336 337
{
	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);

338 339
	pm_runtime_get_sync(&pdev->dev);

340 341
	i2c_del_adapter(&dev->adapter);

342
	dev->disable(dev);
343

344 345
	pm_runtime_dont_use_autosuspend(&pdev->dev);
	pm_runtime_put_sync(&pdev->dev);
346 347
	dw_i2c_plat_pm_cleanup(dev);

348
	reset_control_assert(dev->rst);
349

350 351 352
	return 0;
}

353
#ifdef CONFIG_PM_SLEEP
354
static int dw_i2c_plat_prepare(struct device *dev)
355
{
356 357 358 359 360 361 362
	/*
	 * If the ACPI companion device object is present for this device, it
	 * may be accessed during suspend and resume of other devices via I2C
	 * operation regions, so tell the PM core and middle layers to avoid
	 * skipping system suspend/resume callbacks for it in that case.
	 */
	return !has_acpi_companion(dev);
363 364
}

365
static void dw_i2c_plat_complete(struct device *dev)
366
{
367 368 369 370 371 372 373
	/*
	 * The device can only be in runtime suspend at this point if it has not
	 * been resumed throughout the ending system suspend/resume cycle, so if
	 * the platform firmware might mess up with it, request the runtime PM
	 * framework to resume it.
	 */
	if (pm_runtime_suspended(dev) && pm_resume_via_firmware())
374 375 376
		pm_request_resume(dev);
}
#else
377 378
#define dw_i2c_plat_prepare	NULL
#define dw_i2c_plat_complete	NULL
379 380
#endif

381
#ifdef CONFIG_PM
382
static int dw_i2c_plat_suspend(struct device *dev)
D
Deepak Sikri 已提交
383
{
384
	struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
D
Deepak Sikri 已提交
385

386 387
	i_dev->suspended = true;

388
	if (i_dev->shared_with_punit)
389 390
		return 0;

391
	i_dev->disable(i_dev);
392
	i2c_dw_prepare_clk(i_dev, false);
D
Deepak Sikri 已提交
393 394 395 396

	return 0;
}

397
static int dw_i2c_plat_resume(struct device *dev)
D
Deepak Sikri 已提交
398
{
399
	struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
D
Deepak Sikri 已提交
400

401
	if (!i_dev->shared_with_punit)
402 403
		i2c_dw_prepare_clk(i_dev, true);

404
	i_dev->init(i_dev);
405
	i_dev->suspended = false;
D
Deepak Sikri 已提交
406

407
	return 0;
408 409
}

410
static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
411 412
	.prepare = dw_i2c_plat_prepare,
	.complete = dw_i2c_plat_complete,
413 414
	SET_LATE_SYSTEM_SLEEP_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume)
	SET_RUNTIME_PM_OPS(dw_i2c_plat_suspend, dw_i2c_plat_resume, NULL)
415 416 417 418 419 420
};

#define DW_I2C_DEV_PMOPS (&dw_i2c_dev_pm_ops)
#else
#define DW_I2C_DEV_PMOPS NULL
#endif
421

422
/* Work with hotplug and coldplug */
423 424 425
MODULE_ALIAS("platform:i2c_designware");

static struct platform_driver dw_i2c_driver = {
426 427
	.probe = dw_i2c_plat_probe,
	.remove = dw_i2c_plat_remove,
428 429
	.driver		= {
		.name	= "i2c_designware",
430
		.of_match_table = of_match_ptr(dw_i2c_of_match),
431
		.acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
432
		.pm	= DW_I2C_DEV_PMOPS,
433 434 435 436 437
	},
};

static int __init dw_i2c_init_driver(void)
{
438
	return platform_driver_register(&dw_i2c_driver);
439
}
440
subsys_initcall(dw_i2c_init_driver);
441 442 443 444 445 446 447 448 449 450

static void __exit dw_i2c_exit_driver(void)
{
	platform_driver_unregister(&dw_i2c_driver);
}
module_exit(dw_i2c_exit_driver);

MODULE_AUTHOR("Baruch Siach <baruch@tkos.co.il>");
MODULE_DESCRIPTION("Synopsys DesignWare I2C bus adapter");
MODULE_LICENSE("GPL");