1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright (c) 2018 Arm Ltd.
4  * Author: Liviu Dudau <liviu.dudau@foss.arm.com>
5  *
6  */
7 
8 #include <dm.h>
9 #include <errno.h>
10 #include <i2c.h>
11 #include <asm/io.h>
12 #include <clk.h>
13 #include <linux/bitops.h>
14 #include <linux/delay.h>
15 #include <linux/io.h>
16 
17 #define I2C_CONTROL_REG		0x00
18 #define I2C_SET_REG		0x00
19 #define I2C_CLEAR_REG		0x04
20 
21 #define SCL	BIT(0)
22 #define SDA	BIT(1)
23 
24 struct versatile_i2c_priv {
25 	phys_addr_t base;
26 	u32 delay;
27 };
28 
versatile_sda_set(struct versatile_i2c_priv * priv,u8 state)29 static inline void versatile_sda_set(struct versatile_i2c_priv *priv, u8 state)
30 {
31 	writel(SDA, priv->base + (state ? I2C_SET_REG : I2C_CLEAR_REG));
32 	udelay(priv->delay);
33 }
34 
versatile_sda_get(struct versatile_i2c_priv * priv)35 static inline int versatile_sda_get(struct versatile_i2c_priv *priv)
36 {
37 	int v = !!(readl(priv->base + I2C_CONTROL_REG) & SDA);
38 
39 	udelay(priv->delay);
40 	return v;
41 }
42 
versatile_scl_set(struct versatile_i2c_priv * priv,u8 state)43 static inline void versatile_scl_set(struct versatile_i2c_priv *priv, u8 state)
44 {
45 	writel(SCL, priv->base + (state ? I2C_SET_REG : I2C_CLEAR_REG));
46 	udelay(priv->delay);
47 }
48 
versatile_scl_get(struct versatile_i2c_priv * priv)49 static inline int versatile_scl_get(struct versatile_i2c_priv *priv)
50 {
51 	int v = !!(readl(priv->base + I2C_CONTROL_REG) & SCL);
52 
53 	udelay(priv->delay);
54 	return v;
55 }
56 
57 /* start: SDA goes from high to low while SCL is high */
versatile_i2c_start(struct versatile_i2c_priv * priv)58 static void versatile_i2c_start(struct versatile_i2c_priv *priv)
59 {
60 	udelay(priv->delay);
61 	versatile_sda_set(priv, 1);
62 	versatile_scl_set(priv, 1);
63 	versatile_sda_set(priv, 0);
64 }
65 
66 /* stop: SDA goes from low to high while SCL is high */
versatile_i2c_stop(struct versatile_i2c_priv * priv)67 static void versatile_i2c_stop(struct versatile_i2c_priv *priv)
68 {
69 	versatile_scl_set(priv, 0);
70 	versatile_sda_set(priv, 0);
71 	versatile_scl_set(priv, 1);
72 	versatile_sda_set(priv, 1);
73 }
74 
75 /* read a bit from the SDA line (data or ACK/NACK) */
versatile_i2c_read_bit(struct versatile_i2c_priv * priv)76 static u8 versatile_i2c_read_bit(struct versatile_i2c_priv *priv)
77 {
78 	versatile_scl_set(priv, 0);
79 	versatile_sda_set(priv, 1);
80 	versatile_scl_set(priv, 1);
81 	udelay(priv->delay);
82 	return (u8)versatile_sda_get(priv);
83 }
84 
85 /* write a bit on the SDA line */
versatile_i2c_write_bit(struct versatile_i2c_priv * priv,u8 bit)86 static void versatile_i2c_write_bit(struct versatile_i2c_priv *priv, u8 bit)
87 {
88 	versatile_scl_set(priv, 0);
89 	versatile_sda_set(priv, bit);
90 	versatile_scl_set(priv, 1);
91 	udelay(priv->delay);
92 }
93 
94 /* send a reset sequence of 9 clocks with SDA high */
versatile_i2c_reset_bus(struct versatile_i2c_priv * priv)95 static void versatile_i2c_reset_bus(struct versatile_i2c_priv *priv)
96 {
97 	int i;
98 
99 	for (i = 0; i < 9; i++)
100 		versatile_i2c_write_bit(priv, 1);
101 
102 	versatile_i2c_stop(priv);
103 }
104 
105 /* write byte without start/stop sequence */
versatile_i2c_write_byte(struct versatile_i2c_priv * priv,u8 byte)106 static int versatile_i2c_write_byte(struct versatile_i2c_priv *priv, u8 byte)
107 {
108 	u8 nak, i;
109 
110 	for (i = 0; i < 8; i++) {
111 		versatile_i2c_write_bit(priv, byte & 0x80);
112 		byte <<= 1;
113 	}
114 
115 	/* read ACK */
116 	nak = versatile_i2c_read_bit(priv);
117 	versatile_scl_set(priv, 0);
118 
119 	return nak;	/* not a nack is an ack */
120 }
121 
versatile_i2c_read_byte(struct versatile_i2c_priv * priv,u8 * byte,u8 ack)122 static int versatile_i2c_read_byte(struct versatile_i2c_priv *priv,
123 				   u8 *byte, u8 ack)
124 {
125 	u8 i;
126 
127 	*byte = 0;
128 	for (i = 0; i < 8; i++) {
129 		*byte <<= 1;
130 		*byte |= versatile_i2c_read_bit(priv);
131 	}
132 	/* write the nack */
133 	versatile_i2c_write_bit(priv, ack);
134 
135 	return 0;
136 }
137 
versatile_i2c_send_slave_addr(struct versatile_i2c_priv * priv,struct i2c_msg * msg)138 static int versatile_i2c_send_slave_addr(struct versatile_i2c_priv *priv,
139 					 struct i2c_msg *msg)
140 {
141 	u8 addr;
142 	int ret;
143 
144 	if (msg->flags & I2C_M_TEN) {
145 		/* 10-bit address, send extended address code first */
146 		addr = 0xf0 | ((msg->addr >> 7) & 0x06);
147 		ret = versatile_i2c_write_byte(priv, addr);
148 		if (ret) {
149 			versatile_i2c_stop(priv);
150 			return -EIO;
151 		}
152 
153 		/* remaining bits */
154 		ret = versatile_i2c_write_byte(priv, msg->addr & 0xff);
155 		if (ret) {
156 			versatile_i2c_stop(priv);
157 			return -EIO;
158 		}
159 		/* reads need to resend the addr */
160 		if (msg->flags & I2C_M_RD) {
161 			versatile_i2c_start(priv);
162 			addr |= 1;
163 			ret = versatile_i2c_write_byte(priv, addr);
164 			if (ret) {
165 				versatile_i2c_stop(priv);
166 				return -EIO;
167 			}
168 		}
169 	} else {
170 		/* normal 7-bit address */
171 		addr = msg->addr << 1;
172 		if (msg->flags & I2C_M_RD)
173 			addr |= 1;
174 		ret = versatile_i2c_write_byte(priv, addr);
175 		if (ret) {
176 			versatile_i2c_stop(priv);
177 			return -EIO;
178 		}
179 	}
180 
181 	return 0;
182 }
183 
versatile_i2c_message_xfer(struct versatile_i2c_priv * priv,struct i2c_msg * msg)184 static int versatile_i2c_message_xfer(struct versatile_i2c_priv *priv,
185 				      struct i2c_msg *msg)
186 {
187 	int i, ret;
188 	u8 ack;
189 
190 	versatile_i2c_start(priv);
191 	if (versatile_i2c_send_slave_addr(priv, msg))
192 		return -EIO;
193 
194 	for (i = 0; i < msg->len; i++) {
195 		if (msg->flags & I2C_M_RD) {
196 			ack = (msg->len - i - 1) == 0 ? 1 : 0;
197 			ret = versatile_i2c_read_byte(priv, &msg->buf[i], ack);
198 		} else {
199 			ret = versatile_i2c_write_byte(priv, msg->buf[i]);
200 		}
201 
202 		if (ret)
203 			break;
204 	}
205 
206 	versatile_i2c_stop(priv);
207 
208 	return ret;
209 }
210 
versatile_i2c_xfer(struct udevice * bus,struct i2c_msg * msg,int nmsgs)211 static int versatile_i2c_xfer(struct udevice *bus,
212 			      struct i2c_msg *msg, int nmsgs)
213 {
214 	struct versatile_i2c_priv *priv = dev_get_priv(bus);
215 	int ret;
216 
217 	for ( ; nmsgs > 0; nmsgs--, msg++) {
218 		ret = versatile_i2c_message_xfer(priv, msg);
219 		if (ret)
220 			return -EREMOTEIO;
221 	}
222 
223 	return 0;
224 }
225 
versatile_i2c_chip_probe(struct udevice * bus,uint chip,uint chip_flags)226 static int versatile_i2c_chip_probe(struct udevice *bus,
227 				    uint chip, uint chip_flags)
228 {
229 	/* probe the presence of a slave by writing a 0-size message */
230 	struct i2c_msg msg = { .addr = chip, .flags = chip_flags,
231 			       .len = 0, .buf = NULL };
232 	struct versatile_i2c_priv *priv = dev_get_priv(bus);
233 
234 	return versatile_i2c_message_xfer(priv, &msg);
235 }
236 
versatile_i2c_set_bus_speed(struct udevice * bus,unsigned int speed)237 static int versatile_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
238 {
239 	struct versatile_i2c_priv *priv = dev_get_priv(bus);
240 
241 	priv->delay = 1000000 / (speed << 2);
242 
243 	versatile_i2c_reset_bus(priv);
244 
245 	return 0;
246 }
247 
versatile_i2c_probe(struct udevice * dev)248 static int versatile_i2c_probe(struct udevice *dev)
249 {
250 	struct versatile_i2c_priv *priv = dev_get_priv(dev);
251 
252 	priv->base = (phys_addr_t)dev_read_addr(dev);
253 	priv->delay = 25;	/* 25us * 4 = 100kHz */
254 
255 	return 0;
256 }
257 
258 static const struct dm_i2c_ops versatile_i2c_ops = {
259 	.xfer = versatile_i2c_xfer,
260 	.probe_chip = versatile_i2c_chip_probe,
261 	.set_bus_speed = versatile_i2c_set_bus_speed,
262 };
263 
264 static const struct udevice_id versatile_i2c_of_match[] = {
265 	{ .compatible = "arm,versatile-i2c" },
266 	{ }
267 };
268 
269 U_BOOT_DRIVER(versatile_i2c) = {
270 	.name = "i2c-bus-versatile",
271 	.id = UCLASS_I2C,
272 	.of_match = versatile_i2c_of_match,
273 	.probe = versatile_i2c_probe,
274 	.priv_auto	= sizeof(struct versatile_i2c_priv),
275 	.ops = &versatile_i2c_ops,
276 };
277