i2c-designware-platdrv.c 10.0 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 15
#include <linux/delay.h>
#include <linux/err.h>
16 17
#include <linux/errno.h>
#include <linux/i2c.h>
18
#include <linux/interrupt.h>
19 20
#include <linux/io.h>
#include <linux/kernel.h>
21
#include <linux/mfd/syscon.h>
22
#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/regmap.h>
30
#include <linux/reset.h>
31
#include <linux/sched.h>
32
#include <linux/slab.h>
33
#include <linux/suspend.h>
34

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

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

42 43 44 45
#ifdef CONFIG_ACPI
static const struct acpi_device_id dw_i2c_acpi_match[] = {
	{ "INT33C2", 0 },
	{ "INT33C3", 0 },
46 47
	{ "INT3432", 0 },
	{ "INT3433", 0 },
48
	{ "80860F41", ACCESS_NO_IRQ_SUSPEND },
49
	{ "808622C1", ACCESS_NO_IRQ_SUSPEND },
50
	{ "AMD0010", ACCESS_INTR_MASK },
51
	{ "AMDI0010", ACCESS_INTR_MASK },
52
	{ "AMDI0510", 0 },
53
	{ "APMC0D0F", 0 },
54 55
	{ "HISI02A1", 0 },
	{ "HISI02A2", 0 },
56
	{ "HISI02A3", 0 },
57 58 59 60 61
	{ }
};
MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
#endif

62
#ifdef CONFIG_OF
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
#define BT1_I2C_CTL			0x100
#define BT1_I2C_CTL_ADDR_MASK		GENMASK(7, 0)
#define BT1_I2C_CTL_WR			BIT(8)
#define BT1_I2C_CTL_GO			BIT(31)
#define BT1_I2C_DI			0x104
#define BT1_I2C_DO			0x108

static int bt1_i2c_read(void *context, unsigned int reg, unsigned int *val)
{
	struct dw_i2c_dev *dev = context;
	int ret;

	/*
	 * Note these methods shouldn't ever fail because the system controller
	 * registers are memory mapped. We check the return value just in case.
	 */
	ret = regmap_write(dev->sysmap, BT1_I2C_CTL,
			   BT1_I2C_CTL_GO | (reg & BT1_I2C_CTL_ADDR_MASK));
	if (ret)
		return ret;

	return regmap_read(dev->sysmap, BT1_I2C_DO, val);
}

static int bt1_i2c_write(void *context, unsigned int reg, unsigned int val)
{
	struct dw_i2c_dev *dev = context;
	int ret;

	ret = regmap_write(dev->sysmap, BT1_I2C_DI, val);
	if (ret)
		return ret;

	return regmap_write(dev->sysmap, BT1_I2C_CTL,
		BT1_I2C_CTL_GO | BT1_I2C_CTL_WR | (reg & BT1_I2C_CTL_ADDR_MASK));
}

static struct regmap_config bt1_i2c_cfg = {
	.reg_bits = 32,
	.val_bits = 32,
	.reg_stride = 4,
	.fast_io = true,
	.reg_read = bt1_i2c_read,
	.reg_write = bt1_i2c_write,
	.max_register = DW_IC_COMP_TYPE,
};

static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
{
	dev->sysmap = syscon_node_to_regmap(dev->dev->of_node->parent);
	if (IS_ERR(dev->sysmap))
		return PTR_ERR(dev->sysmap);

	dev->map = devm_regmap_init(dev->dev, NULL, dev, &bt1_i2c_cfg);
	return PTR_ERR_OR_ZERO(dev->map);
}

120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
#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:
138
		dev->ext = devm_platform_ioremap_resource(pdev, 1);
139 140 141 142 143 144 145 146 147 148
		if (!IS_ERR(dev->ext))
			dev->set_sda_hold_time = mscc_twi_set_sda_hold_time;
		break;
	default:
		break;
	}

	return 0;
}

149 150
static const struct of_device_id dw_i2c_of_match[] = {
	{ .compatible = "snps,designware-i2c", },
151
	{ .compatible = "mscc,ocelot-i2c", .data = (void *)MODEL_MSCC_OCELOT },
152
	{ .compatible = "baikal,bt1-sys-i2c", .data = (void *)MODEL_BAIKAL_BT1 },
153 154 155
	{},
};
MODULE_DEVICE_TABLE(of, dw_i2c_of_match);
156
#else
157
static int bt1_i2c_request_regs(struct dw_i2c_dev *dev)
158 159 160
{
	return -ENODEV;
}
161

162
static inline int dw_i2c_of_configure(struct platform_device *pdev)
163
{
164
	return -ENODEV;
165
}
166
#endif
167

168 169 170 171
static void dw_i2c_plat_pm_cleanup(struct dw_i2c_dev *dev)
{
	pm_runtime_disable(dev->dev);

172
	if (dev->shared_with_punit)
173 174 175
		pm_runtime_put_noidle(dev->dev);
}

176 177 178
static int dw_i2c_plat_request_regs(struct dw_i2c_dev *dev)
{
	struct platform_device *pdev = to_platform_device(dev->dev);
179
	int ret;
180

181 182 183 184 185 186 187 188 189
	switch (dev->flags & MODEL_MASK) {
	case MODEL_BAIKAL_BT1:
		ret = bt1_i2c_request_regs(dev);
		break;
	default:
		dev->base = devm_platform_ioremap_resource(pdev, 0);
		ret = PTR_ERR_OR_ZERO(dev->base);
		break;
	}
190

191
	return ret;
192
}
193

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

	irq = platform_get_irq(pdev, 0);
203 204
	if (irq < 0)
		return irq;
205

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

210
	dev->flags = (uintptr_t)device_get_match_data(&pdev->dev);
211
	dev->dev = &pdev->dev;
212 213 214
	dev->irq = irq;
	platform_set_drvdata(pdev, dev);

215 216 217 218
	ret = dw_i2c_plat_request_regs(dev);
	if (ret)
		return ret;

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

	reset_control_deassert(dev->rst);
224

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

231
	i2c_dw_acpi_adjust_bus_speed(&pdev->dev);
232

233 234 235
	if (pdev->dev.of_node)
		dw_i2c_of_configure(pdev);

236
	if (has_acpi_companion(&pdev->dev))
237
		i2c_dw_acpi_configure(&pdev->dev);
238

239 240
	ret = i2c_dw_validate_speed(dev);
	if (ret)
241
		goto exit_reset;
242

243 244
	ret = i2c_dw_probe_lock_support(dev);
	if (ret)
245
		goto exit_reset;
246

247
	i2c_dw_configure(dev);
248

249 250
	/* Optional interface clock */
	dev->pclk = devm_clk_get_optional(&pdev->dev, "pclk");
251 252 253 254
	if (IS_ERR(dev->pclk)) {
		ret = PTR_ERR(dev->pclk);
		goto exit_reset;
	}
255

256
	dev->clk = devm_clk_get(&pdev->dev, NULL);
257
	if (!i2c_dw_prepare_clk(dev, true)) {
258 259
		u64 clk_khz;

260
		dev->get_clk_rate_khz = i2c_dw_get_clk_rate_khz;
261
		clk_khz = dev->get_clk_rate_khz(dev);
262

263 264 265
		if (!dev->sda_hold_time && t->sda_hold_ns)
			dev->sda_hold_time =
				div_u64(clk_khz * t->sda_hold_ns + 500000, 1000000);
266 267
	}

268 269
	adap = &dev->adapter;
	adap->owner = THIS_MODULE;
270
	adap->class = I2C_CLASS_DEPRECATED;
271
	ACPI_COMPANION_SET(&adap->dev, ACPI_COMPANION(&pdev->dev));
272
	adap->dev.of_node = pdev->dev.of_node;
273
	adap->nr = -1;
274

275 276 277
	if (dev->flags & ACCESS_NO_IRQ_SUSPEND) {
		dev_pm_set_driver_flags(&pdev->dev,
					DPM_FLAG_SMART_PREPARE |
278
					DPM_FLAG_MAY_SKIP_RESUME);
279 280 281 282
	} else {
		dev_pm_set_driver_flags(&pdev->dev,
					DPM_FLAG_SMART_PREPARE |
					DPM_FLAG_SMART_SUSPEND |
283
					DPM_FLAG_MAY_SKIP_RESUME);
284
	}
285

286 287 288 289 290 291 292
	/* 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);

293
	if (dev->shared_with_punit)
294 295 296
		pm_runtime_get_noresume(&pdev->dev);

	pm_runtime_enable(&pdev->dev);
297

298
	ret = i2c_dw_probe(dev);
299
	if (ret)
300
		goto exit_probe;
301

302
	return ret;
303 304

exit_probe:
305
	dw_i2c_plat_pm_cleanup(dev);
306
exit_reset:
307
	reset_control_assert(dev->rst);
308
	return ret;
309 310
}

311
static int dw_i2c_plat_remove(struct platform_device *pdev)
312 313 314
{
	struct dw_i2c_dev *dev = platform_get_drvdata(pdev);

315 316
	pm_runtime_get_sync(&pdev->dev);

317 318
	i2c_del_adapter(&dev->adapter);

319
	dev->disable(dev);
320

321 322
	pm_runtime_dont_use_autosuspend(&pdev->dev);
	pm_runtime_put_sync(&pdev->dev);
323 324
	dw_i2c_plat_pm_cleanup(dev);

325
	reset_control_assert(dev->rst);
326

327 328 329
	return 0;
}

330
#ifdef CONFIG_PM_SLEEP
331
static int dw_i2c_plat_prepare(struct device *dev)
332
{
333 334 335 336 337 338 339
	/*
	 * 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);
340 341
}

342
static void dw_i2c_plat_complete(struct device *dev)
343
{
344 345 346 347 348 349 350
	/*
	 * 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())
351 352 353
		pm_request_resume(dev);
}
#else
354 355
#define dw_i2c_plat_prepare	NULL
#define dw_i2c_plat_complete	NULL
356 357
#endif

358
#ifdef CONFIG_PM
359
static int dw_i2c_plat_suspend(struct device *dev)
D
Deepak Sikri 已提交
360
{
361
	struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
D
Deepak Sikri 已提交
362

363 364
	i_dev->suspended = true;

365
	if (i_dev->shared_with_punit)
366 367
		return 0;

368
	i_dev->disable(i_dev);
369
	i2c_dw_prepare_clk(i_dev, false);
D
Deepak Sikri 已提交
370 371 372 373

	return 0;
}

374
static int dw_i2c_plat_resume(struct device *dev)
D
Deepak Sikri 已提交
375
{
376
	struct dw_i2c_dev *i_dev = dev_get_drvdata(dev);
D
Deepak Sikri 已提交
377

378
	if (!i_dev->shared_with_punit)
379 380
		i2c_dw_prepare_clk(i_dev, true);

381
	i_dev->init(i_dev);
382
	i_dev->suspended = false;
D
Deepak Sikri 已提交
383

384
	return 0;
385 386
}

387
static const struct dev_pm_ops dw_i2c_dev_pm_ops = {
388 389
	.prepare = dw_i2c_plat_prepare,
	.complete = dw_i2c_plat_complete,
390 391
	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)
392 393 394 395 396 397
};

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

399
/* Work with hotplug and coldplug */
400 401 402
MODULE_ALIAS("platform:i2c_designware");

static struct platform_driver dw_i2c_driver = {
403 404
	.probe = dw_i2c_plat_probe,
	.remove = dw_i2c_plat_remove,
405 406
	.driver		= {
		.name	= "i2c_designware",
407
		.of_match_table = of_match_ptr(dw_i2c_of_match),
408
		.acpi_match_table = ACPI_PTR(dw_i2c_acpi_match),
409
		.pm	= DW_I2C_DEV_PMOPS,
410 411 412 413 414
	},
};

static int __init dw_i2c_init_driver(void)
{
415
	return platform_driver_register(&dw_i2c_driver);
416
}
417
subsys_initcall(dw_i2c_init_driver);
418 419 420 421 422 423 424 425 426 427

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");