1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Renesas RCar IIC driver
4 *
5 * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
6 *
7 * Based on
8 * Copyright (C) 2011, 2013 Renesas Solutions Corp.
9 * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
10 */
11
12#include <common.h>
13#include <clk.h>
14#include <dm.h>
15#include <i2c.h>
16#include <asm/io.h>
17#include <linux/bitops.h>
18#include <linux/delay.h>
19
20struct rcar_iic_priv {
21	void __iomem		*base;
22	struct clk		clk;
23	u8			iccl;
24	u8			icch;
25};
26
27#define RCAR_IIC_ICDR		0x00
28#define RCAR_IIC_ICCR		0x04
29#define RCAR_IIC_ICSR		0x08
30#define RCAR_IIC_ICIC		0x0c
31#define RCAR_IIC_ICCL		0x10
32#define RCAR_IIC_ICCH		0x14
33
34/* ICCR */
35#define RCAR_IIC_ICCR_ICE	BIT(7)
36#define RCAR_IIC_ICCR_RACK	BIT(6)
37#define RCAR_IIC_ICCR_RTS	BIT(4)
38#define RCAR_IIC_ICCR_BUSY	BIT(2)
39#define RCAR_IIC_ICCR_SCP	BIT(0)
40
41/* ICSR / ICIC */
42#define RCAR_IC_BUSY		BIT(4)
43#define RCAR_IC_TACK		BIT(2)
44#define RCAR_IC_DTE		BIT(0)
45
46#define IRQ_WAIT 1000
47
48static void sh_irq_dte(struct udevice *dev)
49{
50	struct rcar_iic_priv *priv = dev_get_priv(dev);
51	int i;
52
53	for (i = 0; i < IRQ_WAIT; i++) {
54		if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR))
55			break;
56		udelay(10);
57	}
58}
59
60static int sh_irq_dte_with_tack(struct udevice *dev)
61{
62	struct rcar_iic_priv *priv = dev_get_priv(dev);
63	u8 icsr;
64	int i;
65
66	for (i = 0; i < IRQ_WAIT; i++) {
67		icsr = readb(priv->base + RCAR_IIC_ICSR);
68		if (RCAR_IC_DTE & icsr)
69			break;
70		if (RCAR_IC_TACK & icsr)
71			return -ETIMEDOUT;
72		udelay(10);
73	}
74	return 0;
75}
76
77static void sh_irq_busy(struct udevice *dev)
78{
79	struct rcar_iic_priv *priv = dev_get_priv(dev);
80	int i;
81
82	for (i = 0; i < IRQ_WAIT; i++) {
83		if (!(RCAR_IC_BUSY & readb(priv->base + RCAR_IIC_ICSR)))
84			break;
85		udelay(10);
86	}
87}
88
89static int rcar_iic_set_addr(struct udevice *dev, u8 chip, u8 read)
90{
91	struct rcar_iic_priv *priv = dev_get_priv(dev);
92
93	clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
94	setbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
95
96	writeb(priv->iccl, priv->base + RCAR_IIC_ICCL);
97	writeb(priv->icch, priv->base + RCAR_IIC_ICCH);
98	writeb(RCAR_IC_TACK, priv->base + RCAR_IIC_ICIC);
99
100	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS | RCAR_IIC_ICCR_BUSY,
101	       priv->base + RCAR_IIC_ICCR);
102	sh_irq_dte(dev);
103
104	clrbits_8(priv->base + RCAR_IIC_ICSR, RCAR_IC_TACK);
105	writeb(chip << 1 | read, priv->base + RCAR_IIC_ICDR);
106	return sh_irq_dte_with_tack(dev);
107}
108
109static void rcar_iic_finish(struct udevice *dev)
110{
111	struct rcar_iic_priv *priv = dev_get_priv(dev);
112
113	writeb(0, priv->base + RCAR_IIC_ICSR);
114	clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
115}
116
117static int rcar_iic_read_common(struct udevice *dev, struct i2c_msg *msg)
118{
119	struct rcar_iic_priv *priv = dev_get_priv(dev);
120	int i, ret = -EREMOTEIO;
121
122	if (rcar_iic_set_addr(dev, msg->addr, 1) != 0)
123		goto err;
124
125	udelay(10);
126
127	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
128	       priv->base + RCAR_IIC_ICCR);
129
130	for (i = 0; i < msg->len; i++) {
131		if (sh_irq_dte_with_tack(dev) != 0)
132			goto err;
133
134		msg->buf[i] = readb(priv->base + RCAR_IIC_ICDR) & 0xff;
135
136		if (msg->len - 1 == i) {
137			writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RACK,
138			       priv->base + RCAR_IIC_ICCR);
139		}
140	}
141
142	sh_irq_busy(dev);
143	ret = 0;
144
145err:
146	rcar_iic_finish(dev);
147	return ret;
148}
149
150static int rcar_iic_write_common(struct udevice *dev, struct i2c_msg *msg)
151{
152	struct rcar_iic_priv *priv = dev_get_priv(dev);
153	int i, ret = -EREMOTEIO;
154
155	if (rcar_iic_set_addr(dev, msg->addr, 0) != 0)
156		goto err;
157
158	udelay(10);
159
160	for (i = 0; i < msg->len; i++) {
161		writeb(msg->buf[i], priv->base + RCAR_IIC_ICDR);
162		if (sh_irq_dte_with_tack(dev) != 0)
163			goto err;
164	}
165
166	if (msg->flags & I2C_M_STOP) {
167		writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS,
168		       priv->base + RCAR_IIC_ICCR);
169		if (sh_irq_dte_with_tack(dev) != 0)
170			goto err;
171	}
172
173	sh_irq_busy(dev);
174	ret = 0;
175
176err:
177	rcar_iic_finish(dev);
178	return ret;
179}
180
181static int rcar_iic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
182{
183	int ret;
184
185	for (; nmsgs > 0; nmsgs--, msg++) {
186		if (msg->flags & I2C_M_RD)
187			ret = rcar_iic_read_common(dev, msg);
188		else
189			ret = rcar_iic_write_common(dev, msg);
190
191		if (ret)
192			return -EREMOTEIO;
193	}
194
195	return ret;
196}
197
198static int rcar_iic_set_speed(struct udevice *dev, uint speed)
199{
200	struct rcar_iic_priv *priv = dev_get_priv(dev);
201	const unsigned int ratio_high = 4;
202	const unsigned int ratio_low = 5;
203	int clkrate, denom;
204
205	clkrate = clk_get_rate(&priv->clk);
206	if (clkrate < 0)
207		return clkrate;
208
209	/*
210	 * Calculate the value for ICCL and ICCH. From the data sheet:
211	 * iccl = (p-clock / transfer-rate) * (L / (L + H))
212	 * icch = (p clock / transfer rate) * (H / (L + H))
213	 * where L and H are the SCL low and high ratio.
214	 */
215	denom = speed * (ratio_high + ratio_low);
216	priv->iccl = DIV_ROUND_CLOSEST(clkrate * ratio_low, denom);
217	priv->icch = DIV_ROUND_CLOSEST(clkrate * ratio_high, denom);
218
219	return 0;
220}
221
222static int rcar_iic_probe_chip(struct udevice *dev, uint addr, uint flags)
223{
224	struct rcar_iic_priv *priv = dev_get_priv(dev);
225	int ret;
226
227	rcar_iic_set_addr(dev, addr, 1);
228	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
229	       priv->base + RCAR_IIC_ICCR);
230	ret = sh_irq_dte_with_tack(dev);
231	rcar_iic_finish(dev);
232
233	return ret;
234}
235
236static int rcar_iic_probe(struct udevice *dev)
237{
238	struct rcar_iic_priv *priv = dev_get_priv(dev);
239	int ret;
240
241	priv->base = dev_read_addr_ptr(dev);
242
243	ret = clk_get_by_index(dev, 0, &priv->clk);
244	if (ret)
245		return ret;
246
247	ret = clk_enable(&priv->clk);
248	if (ret)
249		return ret;
250
251	rcar_iic_finish(dev);
252
253	return rcar_iic_set_speed(dev, I2C_SPEED_STANDARD_RATE);
254}
255
256static const struct dm_i2c_ops rcar_iic_ops = {
257	.xfer		= rcar_iic_xfer,
258	.probe_chip	= rcar_iic_probe_chip,
259	.set_bus_speed	= rcar_iic_set_speed,
260};
261
262static const struct udevice_id rcar_iic_ids[] = {
263	{ .compatible = "renesas,rmobile-iic" },
264	{ }
265};
266
267U_BOOT_DRIVER(iic_rcar) = {
268	.name		= "iic_rcar",
269	.id		= UCLASS_I2C,
270	.of_match	= rcar_iic_ids,
271	.probe		= rcar_iic_probe,
272	.priv_auto	= sizeof(struct rcar_iic_priv),
273	.ops		= &rcar_iic_ops,
274};
275