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