Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 67240dfc authored by Wolfram Sang's avatar Wolfram Sang Committed by Wolfram Sang
Browse files

i2c: sh_mobile: fix clock calculation for newer SoCs



Newer SoCs have so fast input clocks that the ICCL/H registers only
count every second clock to have a meaningful 9-bit range. The driver
was already prepared for that happening, but didn't use it so far.
Add the proper DT configuration for SoCs that need it.

Signed-off-by: default avatarWolfram Sang <wsa+renesas@sang-engineering.com>
Signed-off-by: default avatarWolfram Sang <wsa@the-dreams.de>
parent 7663ebef
Loading
Loading
Loading
Loading
+38 −10
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@
#include <linux/clk.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/of_device.h>
#include <linux/i2c/i2c-sh_mobile.h>

/* Transmit operation:                                                      */
@@ -139,6 +140,10 @@ struct sh_mobile_i2c_data {
	bool send_stop;
};

struct sh_mobile_dt_config {
	int clks_per_count;
};

#define IIC_FLAG_HAS_ICIC67	(1 << 0)

#define STANDARD_MODE		100000
@@ -617,6 +622,22 @@ static struct i2c_algorithm sh_mobile_i2c_algorithm = {
	.master_xfer	= sh_mobile_i2c_xfer,
};

static const struct sh_mobile_dt_config default_dt_config = {
	.clks_per_count = 1,
};

static const struct sh_mobile_dt_config rcar_gen2_dt_config = {
	.clks_per_count = 2,
};

static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
	{ .compatible = "renesas,rmobile-iic", .data = &default_dt_config },
	{ .compatible = "renesas,iic-r8a7790", .data = &rcar_gen2_dt_config },
	{ .compatible = "renesas,iic-r8a7791", .data = &rcar_gen2_dt_config },
	{},
};
MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids);

static int sh_mobile_i2c_hook_irqs(struct platform_device *dev)
{
	struct resource *res;
@@ -674,11 +695,24 @@ static int sh_mobile_i2c_probe(struct platform_device *dev)
	ret = of_property_read_u32(dev->dev.of_node, "clock-frequency", &bus_speed);
	pd->bus_speed = ret ? STANDARD_MODE : bus_speed;

	pd->clks_per_count = 1;

	if (dev->dev.of_node) {
		const struct of_device_id *match;

		match = of_match_device(sh_mobile_i2c_dt_ids, &dev->dev);
		if (match) {
			const struct sh_mobile_dt_config *config;

			config = match->data;
			pd->clks_per_count = config->clks_per_count;
		}
	} else {
		if (pdata && pdata->bus_speed)
			pd->bus_speed = pdata->bus_speed;
	pd->clks_per_count = 1;
		if (pdata && pdata->clks_per_count)
			pd->clks_per_count = pdata->clks_per_count;
	}

	/* The IIC blocks on SH-Mobile ARM processors
	 * come with two new bits in ICIC.
@@ -758,12 +792,6 @@ static const struct dev_pm_ops sh_mobile_i2c_dev_pm_ops = {
	.runtime_resume = sh_mobile_i2c_runtime_nop,
};

static const struct of_device_id sh_mobile_i2c_dt_ids[] = {
	{ .compatible = "renesas,rmobile-iic", },
	{},
};
MODULE_DEVICE_TABLE(of, sh_mobile_i2c_dt_ids);

static struct platform_driver sh_mobile_i2c_driver = {
	.driver		= {
		.name		= "i2c-sh_mobile",