xref: /openbmc/u-boot/drivers/i2c/rcar_iic.c (revision 606b239a6c60868da1767b973e5f9c3e6eae48fe)
183d290c5STom Rini // SPDX-License-Identifier: GPL-2.0+
29e75ea46SMarek Vasut /*
39e75ea46SMarek Vasut  * Renesas RCar IIC driver
49e75ea46SMarek Vasut  *
59e75ea46SMarek Vasut  * Copyright (C) 2017 Marek Vasut <marek.vasut@gmail.com>
69e75ea46SMarek Vasut  *
79e75ea46SMarek Vasut  * Based on
89e75ea46SMarek Vasut  * Copyright (C) 2011, 2013 Renesas Solutions Corp.
99e75ea46SMarek Vasut  * Copyright (C) 2011, 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com>
109e75ea46SMarek Vasut  */
119e75ea46SMarek Vasut 
129e75ea46SMarek Vasut #include <common.h>
139e75ea46SMarek Vasut #include <clk.h>
149e75ea46SMarek Vasut #include <dm.h>
159e75ea46SMarek Vasut #include <i2c.h>
169e75ea46SMarek Vasut #include <asm/io.h>
179e75ea46SMarek Vasut 
189e75ea46SMarek Vasut struct rcar_iic_priv {
199e75ea46SMarek Vasut 	void __iomem		*base;
209e75ea46SMarek Vasut 	struct clk		clk;
219e75ea46SMarek Vasut 	u8			iccl;
229e75ea46SMarek Vasut 	u8			icch;
239e75ea46SMarek Vasut };
249e75ea46SMarek Vasut 
259e75ea46SMarek Vasut #define RCAR_IIC_ICDR		0x00
269e75ea46SMarek Vasut #define RCAR_IIC_ICCR		0x04
279e75ea46SMarek Vasut #define RCAR_IIC_ICSR		0x08
289e75ea46SMarek Vasut #define RCAR_IIC_ICIC		0x0c
299e75ea46SMarek Vasut #define RCAR_IIC_ICCL		0x10
309e75ea46SMarek Vasut #define RCAR_IIC_ICCH		0x14
319e75ea46SMarek Vasut 
329e75ea46SMarek Vasut /* ICCR */
339e75ea46SMarek Vasut #define RCAR_IIC_ICCR_ICE	BIT(7)
349e75ea46SMarek Vasut #define RCAR_IIC_ICCR_RACK	BIT(6)
359e75ea46SMarek Vasut #define RCAR_IIC_ICCR_RTS	BIT(4)
369e75ea46SMarek Vasut #define RCAR_IIC_ICCR_BUSY	BIT(2)
379e75ea46SMarek Vasut #define RCAR_IIC_ICCR_SCP	BIT(0)
389e75ea46SMarek Vasut 
399e75ea46SMarek Vasut /* ICSR / ICIC */
409e75ea46SMarek Vasut #define RCAR_IC_BUSY		BIT(4)
419e75ea46SMarek Vasut #define RCAR_IC_TACK		BIT(2)
429e75ea46SMarek Vasut #define RCAR_IC_DTE		BIT(0)
439e75ea46SMarek Vasut 
449e75ea46SMarek Vasut #define IRQ_WAIT 1000
459e75ea46SMarek Vasut 
sh_irq_dte(struct udevice * dev)469e75ea46SMarek Vasut static void sh_irq_dte(struct udevice *dev)
479e75ea46SMarek Vasut {
489e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
499e75ea46SMarek Vasut 	int i;
509e75ea46SMarek Vasut 
519e75ea46SMarek Vasut 	for (i = 0; i < IRQ_WAIT; i++) {
529e75ea46SMarek Vasut 		if (RCAR_IC_DTE & readb(priv->base + RCAR_IIC_ICSR))
539e75ea46SMarek Vasut 			break;
549e75ea46SMarek Vasut 		udelay(10);
559e75ea46SMarek Vasut 	}
569e75ea46SMarek Vasut }
579e75ea46SMarek Vasut 
sh_irq_dte_with_tack(struct udevice * dev)589e75ea46SMarek Vasut static int sh_irq_dte_with_tack(struct udevice *dev)
599e75ea46SMarek Vasut {
609e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
61*eb54682eSMarek Vasut 	u8 icsr;
629e75ea46SMarek Vasut 	int i;
639e75ea46SMarek Vasut 
649e75ea46SMarek Vasut 	for (i = 0; i < IRQ_WAIT; i++) {
65*eb54682eSMarek Vasut 		icsr = readb(priv->base + RCAR_IIC_ICSR);
66*eb54682eSMarek Vasut 		if (RCAR_IC_DTE & icsr)
679e75ea46SMarek Vasut 			break;
68*eb54682eSMarek Vasut 		if (RCAR_IC_TACK & icsr)
699e75ea46SMarek Vasut 			return -ETIMEDOUT;
709e75ea46SMarek Vasut 		udelay(10);
719e75ea46SMarek Vasut 	}
729e75ea46SMarek Vasut 	return 0;
739e75ea46SMarek Vasut }
749e75ea46SMarek Vasut 
sh_irq_busy(struct udevice * dev)759e75ea46SMarek Vasut static void sh_irq_busy(struct udevice *dev)
769e75ea46SMarek Vasut {
779e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
789e75ea46SMarek Vasut 	int i;
799e75ea46SMarek Vasut 
809e75ea46SMarek Vasut 	for (i = 0; i < IRQ_WAIT; i++) {
819e75ea46SMarek Vasut 		if (!(RCAR_IC_BUSY & readb(priv->base + RCAR_IIC_ICSR)))
829e75ea46SMarek Vasut 			break;
839e75ea46SMarek Vasut 		udelay(10);
849e75ea46SMarek Vasut 	}
859e75ea46SMarek Vasut }
869e75ea46SMarek Vasut 
rcar_iic_set_addr(struct udevice * dev,u8 chip,u8 read)879e75ea46SMarek Vasut static int rcar_iic_set_addr(struct udevice *dev, u8 chip, u8 read)
889e75ea46SMarek Vasut {
899e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
909e75ea46SMarek Vasut 
919e75ea46SMarek Vasut 	clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
929e75ea46SMarek Vasut 	setbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
939e75ea46SMarek Vasut 
949e75ea46SMarek Vasut 	writeb(priv->iccl, priv->base + RCAR_IIC_ICCL);
959e75ea46SMarek Vasut 	writeb(priv->icch, priv->base + RCAR_IIC_ICCH);
969e75ea46SMarek Vasut 	writeb(RCAR_IC_TACK, priv->base + RCAR_IIC_ICIC);
979e75ea46SMarek Vasut 
989e75ea46SMarek Vasut 	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS | RCAR_IIC_ICCR_BUSY,
999e75ea46SMarek Vasut 	       priv->base + RCAR_IIC_ICCR);
1009e75ea46SMarek Vasut 	sh_irq_dte(dev);
1019e75ea46SMarek Vasut 
1029e75ea46SMarek Vasut 	clrbits_8(priv->base + RCAR_IIC_ICSR, RCAR_IC_TACK);
1039e75ea46SMarek Vasut 	writeb(chip << 1 | read, priv->base + RCAR_IIC_ICDR);
1049e75ea46SMarek Vasut 	return sh_irq_dte_with_tack(dev);
1059e75ea46SMarek Vasut }
1069e75ea46SMarek Vasut 
rcar_iic_finish(struct udevice * dev)1079e75ea46SMarek Vasut static void rcar_iic_finish(struct udevice *dev)
1089e75ea46SMarek Vasut {
1099e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
1109e75ea46SMarek Vasut 
1119e75ea46SMarek Vasut 	writeb(0, priv->base + RCAR_IIC_ICSR);
1129e75ea46SMarek Vasut 	clrbits_8(priv->base + RCAR_IIC_ICCR, RCAR_IIC_ICCR_ICE);
1139e75ea46SMarek Vasut }
1149e75ea46SMarek Vasut 
rcar_iic_read_common(struct udevice * dev,struct i2c_msg * msg)1159e75ea46SMarek Vasut static int rcar_iic_read_common(struct udevice *dev, struct i2c_msg *msg)
1169e75ea46SMarek Vasut {
1179e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
1189e75ea46SMarek Vasut 	int i, ret = -EREMOTEIO;
1199e75ea46SMarek Vasut 
1209e75ea46SMarek Vasut 	if (rcar_iic_set_addr(dev, msg->addr, 1) != 0)
1219e75ea46SMarek Vasut 		goto err;
1229e75ea46SMarek Vasut 
1239e75ea46SMarek Vasut 	udelay(10);
1249e75ea46SMarek Vasut 
1259e75ea46SMarek Vasut 	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
1269e75ea46SMarek Vasut 	       priv->base + RCAR_IIC_ICCR);
1279e75ea46SMarek Vasut 
1289e75ea46SMarek Vasut 	for (i = 0; i < msg->len; i++) {
1299e75ea46SMarek Vasut 		if (sh_irq_dte_with_tack(dev) != 0)
1309e75ea46SMarek Vasut 			goto err;
1319e75ea46SMarek Vasut 
1329e75ea46SMarek Vasut 		msg->buf[i] = readb(priv->base + RCAR_IIC_ICDR) & 0xff;
1339e75ea46SMarek Vasut 
1349e75ea46SMarek Vasut 		if (msg->len - 1 == i) {
1359e75ea46SMarek Vasut 			writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RACK,
1369e75ea46SMarek Vasut 			       priv->base + RCAR_IIC_ICCR);
1379e75ea46SMarek Vasut 		}
1389e75ea46SMarek Vasut 	}
1399e75ea46SMarek Vasut 
1409e75ea46SMarek Vasut 	sh_irq_busy(dev);
1419e75ea46SMarek Vasut 	ret = 0;
1429e75ea46SMarek Vasut 
1439e75ea46SMarek Vasut err:
1449e75ea46SMarek Vasut 	rcar_iic_finish(dev);
1459e75ea46SMarek Vasut 	return ret;
1469e75ea46SMarek Vasut }
1479e75ea46SMarek Vasut 
rcar_iic_write_common(struct udevice * dev,struct i2c_msg * msg)1489e75ea46SMarek Vasut static int rcar_iic_write_common(struct udevice *dev, struct i2c_msg *msg)
1499e75ea46SMarek Vasut {
1509e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
1519e75ea46SMarek Vasut 	int i, ret = -EREMOTEIO;
1529e75ea46SMarek Vasut 
1539e75ea46SMarek Vasut 	if (rcar_iic_set_addr(dev, msg->addr, 0) != 0)
1549e75ea46SMarek Vasut 		goto err;
1559e75ea46SMarek Vasut 
1569e75ea46SMarek Vasut 	udelay(10);
1579e75ea46SMarek Vasut 
1589e75ea46SMarek Vasut 	for (i = 0; i < msg->len; i++) {
1599e75ea46SMarek Vasut 		writeb(msg->buf[i], priv->base + RCAR_IIC_ICDR);
1609e75ea46SMarek Vasut 		if (sh_irq_dte_with_tack(dev) != 0)
1619e75ea46SMarek Vasut 			goto err;
1629e75ea46SMarek Vasut 	}
1639e75ea46SMarek Vasut 
1649e75ea46SMarek Vasut 	if (msg->flags & I2C_M_STOP) {
1659e75ea46SMarek Vasut 		writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_RTS,
1669e75ea46SMarek Vasut 		       priv->base + RCAR_IIC_ICCR);
1679e75ea46SMarek Vasut 		if (sh_irq_dte_with_tack(dev) != 0)
1689e75ea46SMarek Vasut 			goto err;
1699e75ea46SMarek Vasut 	}
1709e75ea46SMarek Vasut 
1719e75ea46SMarek Vasut 	sh_irq_busy(dev);
1729e75ea46SMarek Vasut 	ret = 0;
1739e75ea46SMarek Vasut 
1749e75ea46SMarek Vasut err:
1759e75ea46SMarek Vasut 	rcar_iic_finish(dev);
1769e75ea46SMarek Vasut 	return ret;
1779e75ea46SMarek Vasut }
1789e75ea46SMarek Vasut 
rcar_iic_xfer(struct udevice * dev,struct i2c_msg * msg,int nmsgs)1799e75ea46SMarek Vasut static int rcar_iic_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
1809e75ea46SMarek Vasut {
1819e75ea46SMarek Vasut 	int ret;
1829e75ea46SMarek Vasut 
1839e75ea46SMarek Vasut 	for (; nmsgs > 0; nmsgs--, msg++) {
1849e75ea46SMarek Vasut 		if (msg->flags & I2C_M_RD)
1859e75ea46SMarek Vasut 			ret = rcar_iic_read_common(dev, msg);
1869e75ea46SMarek Vasut 		else
1879e75ea46SMarek Vasut 			ret = rcar_iic_write_common(dev, msg);
1889e75ea46SMarek Vasut 
1899e75ea46SMarek Vasut 		if (ret)
1909e75ea46SMarek Vasut 			return -EREMOTEIO;
1919e75ea46SMarek Vasut 	}
1929e75ea46SMarek Vasut 
1939e75ea46SMarek Vasut 	return ret;
1949e75ea46SMarek Vasut }
1959e75ea46SMarek Vasut 
rcar_iic_set_speed(struct udevice * dev,uint speed)1969e75ea46SMarek Vasut static int rcar_iic_set_speed(struct udevice *dev, uint speed)
1979e75ea46SMarek Vasut {
1989e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
1999e75ea46SMarek Vasut 	const unsigned int ratio_high = 4;
2009e75ea46SMarek Vasut 	const unsigned int ratio_low = 5;
2019e75ea46SMarek Vasut 	int clkrate, denom;
2029e75ea46SMarek Vasut 
2039e75ea46SMarek Vasut 	clkrate = clk_get_rate(&priv->clk);
2049e75ea46SMarek Vasut 	if (clkrate < 0)
2059e75ea46SMarek Vasut 		return clkrate;
2069e75ea46SMarek Vasut 
2079e75ea46SMarek Vasut 	/*
2089e75ea46SMarek Vasut 	 * Calculate the value for ICCL and ICCH. From the data sheet:
2099e75ea46SMarek Vasut 	 * iccl = (p-clock / transfer-rate) * (L / (L + H))
2109e75ea46SMarek Vasut 	 * icch = (p clock / transfer rate) * (H / (L + H))
2119e75ea46SMarek Vasut 	 * where L and H are the SCL low and high ratio.
2129e75ea46SMarek Vasut 	 */
2139e75ea46SMarek Vasut 	denom = speed * (ratio_high + ratio_low);
2149e75ea46SMarek Vasut 	priv->iccl = DIV_ROUND_CLOSEST(clkrate * ratio_low, denom);
2159e75ea46SMarek Vasut 	priv->icch = DIV_ROUND_CLOSEST(clkrate * ratio_high, denom);
2169e75ea46SMarek Vasut 
2179e75ea46SMarek Vasut 	return 0;
2189e75ea46SMarek Vasut }
2199e75ea46SMarek Vasut 
rcar_iic_probe_chip(struct udevice * dev,uint addr,uint flags)2209e75ea46SMarek Vasut static int rcar_iic_probe_chip(struct udevice *dev, uint addr, uint flags)
2219e75ea46SMarek Vasut {
2229e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
2239e75ea46SMarek Vasut 	int ret;
2249e75ea46SMarek Vasut 
2259e75ea46SMarek Vasut 	rcar_iic_set_addr(dev, addr, 1);
2269e75ea46SMarek Vasut 	writeb(RCAR_IIC_ICCR_ICE | RCAR_IIC_ICCR_SCP,
2279e75ea46SMarek Vasut 	       priv->base + RCAR_IIC_ICCR);
2289e75ea46SMarek Vasut 	ret = sh_irq_dte_with_tack(dev);
2299e75ea46SMarek Vasut 	rcar_iic_finish(dev);
2309e75ea46SMarek Vasut 
2319e75ea46SMarek Vasut 	return ret;
2329e75ea46SMarek Vasut }
2339e75ea46SMarek Vasut 
rcar_iic_probe(struct udevice * dev)2349e75ea46SMarek Vasut static int rcar_iic_probe(struct udevice *dev)
2359e75ea46SMarek Vasut {
2369e75ea46SMarek Vasut 	struct rcar_iic_priv *priv = dev_get_priv(dev);
2379e75ea46SMarek Vasut 	int ret;
2389e75ea46SMarek Vasut 
2399e75ea46SMarek Vasut 	priv->base = dev_read_addr_ptr(dev);
2409e75ea46SMarek Vasut 
2419e75ea46SMarek Vasut 	ret = clk_get_by_index(dev, 0, &priv->clk);
2429e75ea46SMarek Vasut 	if (ret)
2439e75ea46SMarek Vasut 		return ret;
2449e75ea46SMarek Vasut 
2459e75ea46SMarek Vasut 	ret = clk_enable(&priv->clk);
2469e75ea46SMarek Vasut 	if (ret)
2479e75ea46SMarek Vasut 		return ret;
2489e75ea46SMarek Vasut 
2499e75ea46SMarek Vasut 	rcar_iic_finish(dev);
2509e75ea46SMarek Vasut 
2519e75ea46SMarek Vasut 	return rcar_iic_set_speed(dev, 100000);
2529e75ea46SMarek Vasut }
2539e75ea46SMarek Vasut 
2549e75ea46SMarek Vasut static const struct dm_i2c_ops rcar_iic_ops = {
2559e75ea46SMarek Vasut 	.xfer		= rcar_iic_xfer,
2569e75ea46SMarek Vasut 	.probe_chip	= rcar_iic_probe_chip,
2579e75ea46SMarek Vasut 	.set_bus_speed	= rcar_iic_set_speed,
2589e75ea46SMarek Vasut };
2599e75ea46SMarek Vasut 
2609e75ea46SMarek Vasut static const struct udevice_id rcar_iic_ids[] = {
2619e75ea46SMarek Vasut 	{ .compatible = "renesas,rmobile-iic" },
2629e75ea46SMarek Vasut 	{ }
2639e75ea46SMarek Vasut };
2649e75ea46SMarek Vasut 
2659e75ea46SMarek Vasut U_BOOT_DRIVER(iic_rcar) = {
2669e75ea46SMarek Vasut 	.name		= "iic_rcar",
2679e75ea46SMarek Vasut 	.id		= UCLASS_I2C,
2689e75ea46SMarek Vasut 	.of_match	= rcar_iic_ids,
2699e75ea46SMarek Vasut 	.probe		= rcar_iic_probe,
2709e75ea46SMarek Vasut 	.priv_auto_alloc_size = sizeof(struct rcar_iic_priv),
2719e75ea46SMarek Vasut 	.ops		= &rcar_iic_ops,
2729e75ea46SMarek Vasut };
273