1 /*
2  * Copyright (c) 2018 SiFive Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT sifive_i2c0
8 
9 #define LOG_LEVEL CONFIG_I2C_LOG_LEVEL
10 #include <logging/log.h>
11 LOG_MODULE_REGISTER(i2c_sifive);
12 
13 #include <device.h>
14 #include <drivers/i2c.h>
15 #include <sys/sys_io.h>
16 
17 #include "i2c-priv.h"
18 
19 /* Macros */
20 
21 #define I2C_REG(config, reg)	((mem_addr_t) ((config)->base + reg))
22 #define IS_SET(config, reg, value) (sys_read8(I2C_REG(config, reg)) & (value))
23 
24 /* Register Offsets */
25 
26 #define REG_PRESCALE_LOW	0x00
27 #define REG_PRESCALE_HIGH	0x04
28 
29 #define REG_CONTROL		0x08
30 
31 /* Transmit on write, receive on read */
32 #define REG_TRANSMIT		0x0c
33 #define REG_RECEIVE		0x0c
34 
35 /* Command on write, status on read */
36 #define REG_COMMAND		0x10
37 #define REG_STATUS		0x10
38 
39 /* Values */
40 
41 #define SF_CONTROL_EN	(1 << 7)
42 #define SF_CONTROL_IE	(1 << 6)
43 
44 #define SF_TX_WRITE	(0 << 0)
45 #define SF_TX_READ	(1 << 0)
46 
47 #define SF_CMD_START	(1 << 7)
48 #define SF_CMD_STOP	(1 << 6)
49 #define SF_CMD_READ	(1 << 5)
50 #define SF_CMD_WRITE	(1 << 4)
51 #define SF_CMD_ACK	(1 << 3)
52 #define SF_CMD_IACK	(1 << 0)
53 
54 #define SF_STATUS_RXACK	(1 << 7)
55 #define SF_STATUS_BUSY	(1 << 6)
56 #define SF_STATUS_AL	(1 << 5)
57 #define SF_STATUS_TIP	(1 << 1)
58 #define SF_STATUS_IP	(1 << 0)
59 
60 /* Structure declarations */
61 
62 struct i2c_sifive_cfg {
63 	uint32_t base;
64 	uint32_t f_sys;
65 	uint32_t f_bus;
66 };
67 
68 /* Helper functions */
69 
i2c_sifive_busy(const struct device * dev)70 static inline bool i2c_sifive_busy(const struct device *dev)
71 {
72 	const struct i2c_sifive_cfg *config = dev->config;
73 
74 	return IS_SET(config, REG_STATUS, SF_STATUS_TIP);
75 }
76 
i2c_sifive_send_addr(const struct device * dev,uint16_t addr,uint16_t rw_flag)77 static int i2c_sifive_send_addr(const struct device *dev,
78 				uint16_t addr,
79 				uint16_t rw_flag)
80 {
81 	const struct i2c_sifive_cfg *config = dev->config;
82 	uint8_t command = 0U;
83 
84 	/* Wait for a previous transfer to complete */
85 	while (i2c_sifive_busy(dev)) {
86 	}
87 
88 	/* Set transmit register to address with read/write flag */
89 	sys_write8((addr | rw_flag), I2C_REG(config, REG_TRANSMIT));
90 
91 	/* Addresses are always written */
92 	command = SF_CMD_WRITE | SF_CMD_START;
93 
94 	/* Write the command register to start the transfer */
95 	sys_write8(command, I2C_REG(config, REG_COMMAND));
96 
97 	while (i2c_sifive_busy(dev)) {
98 	}
99 
100 	if (IS_SET(config, REG_STATUS, SF_STATUS_RXACK)) {
101 		LOG_ERR("I2C Rx failed to acknowledge\n");
102 		return -EIO;
103 	}
104 
105 	return 0;
106 }
107 
i2c_sifive_write_msg(const struct device * dev,struct i2c_msg * msg,uint16_t addr)108 static int i2c_sifive_write_msg(const struct device *dev,
109 				struct i2c_msg *msg,
110 				uint16_t addr)
111 {
112 	const struct i2c_sifive_cfg *config = dev->config;
113 	int rc = 0;
114 	uint8_t command = 0U;
115 
116 	rc = i2c_sifive_send_addr(dev, addr, SF_TX_WRITE);
117 	if (rc != 0) {
118 		LOG_ERR("I2C failed to write message\n");
119 		return rc;
120 	}
121 
122 	for (uint32_t i = 0; i < msg->len; i++) {
123 		/* Wait for a previous transfer */
124 		while (i2c_sifive_busy(dev)) {
125 		}
126 
127 		/* Put data in transmit reg */
128 		sys_write8((msg->buf)[i], I2C_REG(config, REG_TRANSMIT));
129 
130 		/* Generate command byte */
131 		command = SF_CMD_WRITE;
132 
133 		/* On the last byte of the message */
134 		if (i == (msg->len - 1)) {
135 			/* If the stop bit is requested, set it */
136 			if (msg->flags & I2C_MSG_STOP) {
137 				command |= SF_CMD_STOP;
138 			}
139 		}
140 
141 		/* Write command reg */
142 		sys_write8(command, I2C_REG(config, REG_COMMAND));
143 
144 		/* Wait for a previous transfer */
145 		while (i2c_sifive_busy(dev)) {
146 		}
147 
148 		if (IS_SET(config, REG_STATUS, SF_STATUS_RXACK)) {
149 			LOG_ERR("I2C Rx failed to acknowledge\n");
150 			return -EIO;
151 		}
152 	}
153 
154 	return 0;
155 }
156 
i2c_sifive_read_msg(const struct device * dev,struct i2c_msg * msg,uint16_t addr)157 static int i2c_sifive_read_msg(const struct device *dev,
158 			       struct i2c_msg *msg,
159 			       uint16_t addr)
160 {
161 	const struct i2c_sifive_cfg *config = dev->config;
162 	uint8_t command = 0U;
163 
164 	i2c_sifive_send_addr(dev, addr, SF_TX_READ);
165 
166 	while (i2c_sifive_busy(dev)) {
167 	}
168 
169 	for (int i = 0; i < msg->len; i++) {
170 		/* Generate command byte */
171 		command = SF_CMD_READ;
172 
173 		/* On the last byte of the message */
174 		if (i == (msg->len - 1)) {
175 			/* Set NACK to end read */
176 			command |= SF_CMD_ACK;
177 
178 			/* If the stop bit is requested, set it */
179 			if (msg->flags & I2C_MSG_STOP) {
180 				command |= SF_CMD_STOP;
181 			}
182 		}
183 
184 		/* Write command reg */
185 		sys_write8(command, I2C_REG(config, REG_COMMAND));
186 
187 		/* Wait for the read to complete */
188 		while (i2c_sifive_busy(dev)) {
189 		}
190 
191 		/* Store the received byte */
192 		(msg->buf)[i] = sys_read8(I2C_REG(config, REG_RECEIVE));
193 	}
194 
195 	return 0;
196 }
197 
198 /* API Functions */
199 
i2c_sifive_configure(const struct device * dev,uint32_t dev_config)200 static int i2c_sifive_configure(const struct device *dev, uint32_t dev_config)
201 {
202 	const struct i2c_sifive_cfg *config = NULL;
203 	uint32_t i2c_speed = 0U;
204 	uint16_t prescale = 0U;
205 
206 	/* Check for NULL pointers */
207 	if (dev == NULL) {
208 		LOG_ERR("Device handle is NULL");
209 		return -EINVAL;
210 	}
211 	config = dev->config;
212 	if (config == NULL) {
213 		LOG_ERR("Device config is NULL");
214 		return -EINVAL;
215 	}
216 
217 	/* Disable the I2C peripheral */
218 	sys_write8(0, I2C_REG(config, REG_CONTROL));
219 
220 	/* Configure bus frequency */
221 	switch (I2C_SPEED_GET(dev_config)) {
222 	case I2C_SPEED_STANDARD:
223 		i2c_speed = 100000U; /* 100 KHz */
224 		break;
225 	case I2C_SPEED_FAST:
226 		i2c_speed = 400000U; /* 400 KHz */
227 		break;
228 	case I2C_SPEED_FAST_PLUS:
229 	case I2C_SPEED_HIGH:
230 	case I2C_SPEED_ULTRA:
231 	default:
232 		LOG_ERR("Unsupported I2C speed requested");
233 		return -ENOTSUP;
234 	}
235 
236 	/* Calculate prescale value */
237 	prescale = (config->f_sys / (i2c_speed * 5U)) - 1;
238 
239 	/* Configure peripheral with calculated prescale */
240 	sys_write8((uint8_t) (0xFF & prescale), I2C_REG(config, REG_PRESCALE_LOW));
241 	sys_write8((uint8_t) (0xFF & (prescale >> 8)),
242 		   I2C_REG(config, REG_PRESCALE_HIGH));
243 
244 	/* Support I2C Master mode only */
245 	if (!(dev_config & I2C_MODE_MASTER)) {
246 		LOG_ERR("I2C only supports operation as master");
247 		return -ENOTSUP;
248 	}
249 
250 	/*
251 	 * Driver does not support 10-bit addressing. This can be added
252 	 * in the future when needed.
253 	 */
254 	if (dev_config & I2C_ADDR_10_BITS) {
255 		LOG_ERR("I2C driver does not support 10-bit addresses");
256 		return -ENOTSUP;
257 	}
258 
259 	/* Enable the I2C peripheral */
260 	sys_write8(SF_CONTROL_EN, I2C_REG(config, REG_CONTROL));
261 
262 	return 0;
263 }
264 
i2c_sifive_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)265 static int i2c_sifive_transfer(const struct device *dev,
266 			       struct i2c_msg *msgs,
267 			       uint8_t num_msgs,
268 			       uint16_t addr)
269 {
270 	int rc = 0;
271 
272 	/* Check for NULL pointers */
273 	if (dev == NULL) {
274 		LOG_ERR("Device handle is NULL");
275 		return -EINVAL;
276 	}
277 	if (dev->config == NULL) {
278 		LOG_ERR("Device config is NULL");
279 		return -EINVAL;
280 	}
281 	if (msgs == NULL) {
282 		return -EINVAL;
283 	}
284 
285 	for (int i = 0; i < num_msgs; i++) {
286 		if (msgs[i].flags & I2C_MSG_READ) {
287 			rc = i2c_sifive_read_msg(dev, &(msgs[i]), addr);
288 		} else {
289 			rc = i2c_sifive_write_msg(dev, &(msgs[i]), addr);
290 		}
291 
292 		if (rc != 0) {
293 			LOG_ERR("I2C failed to transfer messages\n");
294 			return rc;
295 		}
296 	}
297 
298 	return 0;
299 };
300 
i2c_sifive_init(const struct device * dev)301 static int i2c_sifive_init(const struct device *dev)
302 {
303 	const struct i2c_sifive_cfg *config = dev->config;
304 	uint32_t dev_config = 0U;
305 	int rc = 0;
306 
307 	dev_config = (I2C_MODE_MASTER | i2c_map_dt_bitrate(config->f_bus));
308 
309 	rc = i2c_sifive_configure(dev, dev_config);
310 	if (rc != 0) {
311 		LOG_ERR("Failed to configure I2C on init");
312 		return rc;
313 	}
314 
315 	return 0;
316 }
317 
318 
319 static struct i2c_driver_api i2c_sifive_api = {
320 	.configure = i2c_sifive_configure,
321 	.transfer = i2c_sifive_transfer,
322 };
323 
324 /* Device instantiation */
325 
326 #define I2C_SIFIVE_INIT(n) \
327 	static struct i2c_sifive_cfg i2c_sifive_cfg_##n = { \
328 		.base = DT_INST_REG_ADDR(n), \
329 		.f_sys = DT_INST_PROP(n, input_frequency), \
330 		.f_bus = DT_INST_PROP(n, clock_frequency), \
331 	}; \
332 	DEVICE_DT_INST_DEFINE(n, \
333 			    i2c_sifive_init, \
334 			    NULL, \
335 			    NULL, \
336 			    &i2c_sifive_cfg_##n, \
337 			    POST_KERNEL, \
338 			    CONFIG_I2C_INIT_PRIORITY, \
339 			    &i2c_sifive_api);
340 
341 DT_INST_FOREACH_STATUS_OKAY(I2C_SIFIVE_INIT)
342