1 /*
2  * Copyright (c) 2019, Henrik Brix Andersen <henrik@brixandersen.dk>
3  *
4  * Based on the i2c_mcux_lpi2c.c driver, which is:
5  * Copyright (c) 2016 Freescale Semiconductor, Inc.
6  * Copyright (c) 2019, NXP
7  *
8  * SPDX-License-Identifier: Apache-2.0
9  */
10 
11 #define DT_DRV_COMPAT openisa_rv32m1_lpi2c
12 
13 #include <drivers/i2c.h>
14 #include <drivers/clock_control.h>
15 #include <fsl_lpi2c.h>
16 #include <logging/log.h>
17 LOG_MODULE_REGISTER(rv32m1_lpi2c);
18 
19 #include "i2c-priv.h"
20 
21 struct rv32m1_lpi2c_config {
22 	LPI2C_Type *base;
23 	const struct device *clock_dev;
24 	clock_control_subsys_t clock_subsys;
25 	clock_ip_name_t clock_ip_name;
26 	uint32_t clock_ip_src;
27 	uint32_t bitrate;
28 	void (*irq_config_func)(const struct device *dev);
29 };
30 
31 struct rv32m1_lpi2c_data {
32 	lpi2c_master_handle_t handle;
33 	struct k_sem transfer_sync;
34 	struct k_sem completion_sync;
35 	status_t completion_status;
36 };
37 
rv32m1_lpi2c_configure(const struct device * dev,uint32_t dev_config)38 static int rv32m1_lpi2c_configure(const struct device *dev,
39 				  uint32_t dev_config)
40 {
41 	const struct rv32m1_lpi2c_config *config = dev->config;
42 	uint32_t baudrate;
43 	uint32_t clk_freq;
44 	int err;
45 
46 	if (!(I2C_MODE_MASTER & dev_config)) {
47 		/* Slave mode not supported - yet */
48 		LOG_ERR("Slave mode not supported");
49 		return -ENOTSUP;
50 	}
51 
52 	if (I2C_ADDR_10_BITS & dev_config) {
53 		/* FSL LPI2C driver only supports 7-bit addressing */
54 		LOG_ERR("10 bit addressing not supported");
55 		return -ENOTSUP;
56 	}
57 
58 	switch (I2C_SPEED_GET(dev_config)) {
59 	case I2C_SPEED_STANDARD:
60 		baudrate = KHZ(100);
61 		break;
62 	case I2C_SPEED_FAST:
63 		baudrate = KHZ(400);
64 		break;
65 	case I2C_SPEED_FAST_PLUS:
66 		baudrate = MHZ(1);
67 		break;
68 	/* TODO: only if SCL pin implements current source pull-up */
69 	/* case I2C_SPEED_HIGH: */
70 	/*      baudrate = KHZ(3400); */
71 	/*      break; */
72 	/* TODO: ultra-fast requires pin_config setting */
73 	/* case I2C_SPEED_ULTRA: */
74 	/*      baudrate = MHZ(5); */
75 	/*      break; */
76 	default:
77 		LOG_ERR("Unsupported speed");
78 		return -ENOTSUP;
79 	}
80 
81 	err = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clk_freq);
82 	if (err) {
83 		LOG_ERR("Could not get clock frequency (err %d)", err);
84 		return -EINVAL;
85 	}
86 
87 	LPI2C_MasterSetBaudRate(config->base, clk_freq, baudrate);
88 
89 	return 0;
90 }
91 
rv32m1_lpi2c_master_transfer_callback(LPI2C_Type * base,lpi2c_master_handle_t * handle,status_t completionStatus,void * userData)92 static void rv32m1_lpi2c_master_transfer_callback(LPI2C_Type *base,
93 						  lpi2c_master_handle_t *handle,
94 						  status_t completionStatus,
95 						  void *userData)
96 {
97 	struct rv32m1_lpi2c_data *data = userData;
98 
99 	ARG_UNUSED(base);
100 	ARG_UNUSED(handle);
101 
102 	data->completion_status = completionStatus;
103 	k_sem_give(&data->completion_sync);
104 }
105 
rv32m1_lpi2c_convert_flags(int msg_flags)106 static uint32_t rv32m1_lpi2c_convert_flags(int msg_flags)
107 {
108 	uint32_t flags = 0U;
109 
110 	if (!(msg_flags & I2C_MSG_STOP)) {
111 		flags |= kLPI2C_TransferNoStopFlag;
112 	}
113 
114 	if (msg_flags & I2C_MSG_RESTART) {
115 		flags |= kLPI2C_TransferRepeatedStartFlag;
116 	}
117 
118 	return flags;
119 }
120 
rv32m1_lpi2c_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)121 static int rv32m1_lpi2c_transfer(const struct device *dev,
122 				 struct i2c_msg *msgs,
123 				 uint8_t num_msgs, uint16_t addr)
124 {
125 	const struct rv32m1_lpi2c_config *config = dev->config;
126 	struct rv32m1_lpi2c_data *data = dev->data;
127 	lpi2c_master_transfer_t transfer;
128 	status_t status;
129 	int ret = 0;
130 
131 	k_sem_take(&data->transfer_sync, K_FOREVER);
132 
133 	/* Iterate over all the messages */
134 	for (int i = 0; i < num_msgs; i++) {
135 		if (I2C_MSG_ADDR_10_BITS & msgs->flags) {
136 			ret = -ENOTSUP;
137 			goto out;
138 		}
139 
140 		/* Initialize the transfer descriptor */
141 		transfer.flags = rv32m1_lpi2c_convert_flags(msgs->flags);
142 
143 		/* Prevent the controller to send a start condition between
144 		 * messages, except if explicitly requested.
145 		 */
146 		if (i != 0 && !(msgs->flags & I2C_MSG_RESTART)) {
147 			transfer.flags |= kLPI2C_TransferNoStartFlag;
148 		}
149 
150 		transfer.slaveAddress = addr;
151 		transfer.direction = (msgs->flags & I2C_MSG_READ)
152 			? kLPI2C_Read : kLPI2C_Write;
153 		transfer.subaddress = 0;
154 		transfer.subaddressSize = 0;
155 		transfer.data = msgs->buf;
156 		transfer.dataSize = msgs->len;
157 
158 		/* Start the transfer */
159 		status = LPI2C_MasterTransferNonBlocking(config->base,
160 							 &data->handle,
161 							 &transfer);
162 
163 		/* Return an error if the transfer didn't start successfully
164 		 * e.g., if the bus was busy
165 		 */
166 		if (status != kStatus_Success) {
167 			LOG_DBG("Could not start transfer (status %d)", status);
168 			ret = -EIO;
169 			goto out;
170 		}
171 
172 		/* Wait for the transfer to complete */
173 		k_sem_take(&data->completion_sync, K_FOREVER);
174 
175 		/* Return an error if the transfer didn't complete
176 		 * successfully. e.g., nak, timeout, lost arbitration
177 		 */
178 		if (data->completion_status != kStatus_Success) {
179 			LOG_DBG("Transfer failed (status %d)",
180 				data->completion_status);
181 			LPI2C_MasterTransferAbort(config->base, &data->handle);
182 			ret = -EIO;
183 			goto out;
184 		}
185 
186 		/* Move to the next message */
187 		msgs++;
188 	}
189 
190 out:
191 	k_sem_give(&data->transfer_sync);
192 	return ret;
193 }
194 
rv32m1_lpi2c_isr(const struct device * dev)195 static void rv32m1_lpi2c_isr(const struct device *dev)
196 {
197 	const struct rv32m1_lpi2c_config *config = dev->config;
198 	struct rv32m1_lpi2c_data *data = dev->data;
199 
200 	LPI2C_MasterTransferHandleIRQ(config->base, &data->handle);
201 }
202 
rv32m1_lpi2c_init(const struct device * dev)203 static int rv32m1_lpi2c_init(const struct device *dev)
204 {
205 	const struct rv32m1_lpi2c_config *config = dev->config;
206 	struct rv32m1_lpi2c_data *data = dev->data;
207 	lpi2c_master_config_t master_config;
208 	uint32_t clk_freq, dev_cfg;
209 	int err;
210 
211 	CLOCK_SetIpSrc(config->clock_ip_name, config->clock_ip_src);
212 
213 	err = clock_control_on(config->clock_dev, config->clock_subsys);
214 	if (err) {
215 		LOG_ERR("Could not turn on clock (err %d)", err);
216 		return -EINVAL;
217 	}
218 
219 	err = clock_control_get_rate(config->clock_dev, config->clock_subsys, &clk_freq);
220 	if (err) {
221 		LOG_ERR("Could not get clock frequency (err %d)", err);
222 		return -EINVAL;
223 	}
224 
225 	LPI2C_MasterGetDefaultConfig(&master_config);
226 	LPI2C_MasterInit(config->base, &master_config, clk_freq);
227 	LPI2C_MasterTransferCreateHandle(config->base, &data->handle,
228 					 rv32m1_lpi2c_master_transfer_callback,
229 					 data);
230 
231 	dev_cfg = i2c_map_dt_bitrate(config->bitrate);
232 	err = rv32m1_lpi2c_configure(dev, dev_cfg | I2C_MODE_MASTER);
233 	if (err) {
234 		LOG_ERR("Could not configure controller (err %d)", err);
235 		return err;
236 	}
237 
238 	config->irq_config_func(dev);
239 
240 	return 0;
241 }
242 
243 static const struct i2c_driver_api rv32m1_lpi2c_driver_api = {
244 	.configure = rv32m1_lpi2c_configure,
245 	.transfer  = rv32m1_lpi2c_transfer,
246 };
247 
248 #define RV32M1_LPI2C_DEVICE(id)                                                \
249 	static void rv32m1_lpi2c_irq_config_func_##id(const struct device *dev);     \
250 	static const struct rv32m1_lpi2c_config rv32m1_lpi2c_##id##_config = { \
251 		.base =                                                        \
252 		(LPI2C_Type *)DT_INST_REG_ADDR(id),                            \
253 		.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(id)),	       \
254 		.clock_subsys =                                                \
255 			(clock_control_subsys_t) DT_INST_CLOCKS_CELL(id, name),\
256 		.clock_ip_name = INST_DT_CLOCK_IP_NAME(id),                    \
257 		.clock_ip_src  = kCLOCK_IpSrcFircAsync,                        \
258 		.bitrate = DT_INST_PROP(id, clock_frequency),                  \
259 		.irq_config_func = rv32m1_lpi2c_irq_config_func_##id,          \
260 	};                                                                     \
261 	static struct rv32m1_lpi2c_data rv32m1_lpi2c_##id##_data = {           \
262 		.transfer_sync = Z_SEM_INITIALIZER(                            \
263 			rv32m1_lpi2c_##id##_data.transfer_sync, 1, 1),         \
264 		.completion_sync = Z_SEM_INITIALIZER(                          \
265 			rv32m1_lpi2c_##id##_data.completion_sync, 0, 1),       \
266 	};                                                                     \
267 	DEVICE_DT_INST_DEFINE(id,                                              \
268 			    &rv32m1_lpi2c_init,                                \
269 			    NULL,                                              \
270 			    &rv32m1_lpi2c_##id##_data,                         \
271 			    &rv32m1_lpi2c_##id##_config,                       \
272 			    POST_KERNEL, CONFIG_I2C_INIT_PRIORITY,             \
273 			    &rv32m1_lpi2c_driver_api);	                       \
274 	static void rv32m1_lpi2c_irq_config_func_##id(const struct device *dev)      \
275 	{                                                                      \
276 		IRQ_CONNECT(DT_INST_IRQN(id),                                  \
277 			    0,						       \
278 			    rv32m1_lpi2c_isr, DEVICE_DT_INST_GET(id),	       \
279 			    0);                                                \
280 		irq_enable(DT_INST_IRQN(id));                                  \
281 	}                                                                      \
282 
283 DT_INST_FOREACH_STATUS_OKAY(RV32M1_LPI2C_DEVICE)
284