1 /*
2  * Copyright (c) 2023 Microchip Technology Inc.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <errno.h>
8 #include <string.h>
9 #include <zephyr/drivers/i2c.h>
10 #include <zephyr/irq.h>
11 #include <zephyr/device.h>
12 #include <zephyr/drivers/i2c.h>
13 #include <zephyr/sys/util.h>
14 #include <zephyr/irq.h>
15 #include <zephyr/logging/log.h>
16 #include <zephyr/sys/sys_io.h>
17 #include <zephyr/sys/atomic.h>
18 #include <zephyr/sys/barrier.h>
19 LOG_MODULE_REGISTER(i2c_mchp, CONFIG_I2C_LOG_LEVEL);
20 
21 #define DT_DRV_COMPAT microchip_mpfs_i2c
22 
23 #define CORE_I2C_CTRL      (0x00)
24 #define CORE_I2C_STATUS    (0x04)
25 #define CORE_I2C_DATA      (0x08)
26 #define CORE_I2C_ADDR_0    (0x0C)
27 #define CORE_I2C_FREQ      (0x14)
28 #define CORE_I2C_GLITCHREG (0x18)
29 #define CORE_I2C_ADDR_1    (0x1C)
30 
31 #define CTRL_CR0  BIT(0)
32 #define CTRL_CR1  BIT(1)
33 #define CTRL_AA   BIT(2)
34 #define CTRL_SI   BIT(3)
35 #define CTRL_STO  BIT(4)
36 #define CTRL_STA  BIT(5)
37 #define CTRL_ENS1 BIT(6)
38 #define CTRL_CR2  BIT(7)
39 
40 #define STATUS_M_START_SENT                  (0x08)
41 #define STATUS_M_REPEATED_START_SENT         (0x10)
42 #define STATUS_M_SLAW_ACK                    (0x18)
43 #define STATUS_M_SLAW_NACK                   (0x20)
44 #define STATUS_M_TX_DATA_ACK                 (0x28)
45 #define STATUS_M_TX_DATA_NACK                (0x30)
46 #define STATUS_M_ARB_LOST                    (0x38)
47 #define STATUS_M_SLAR_ACK                    (0x40)
48 #define STATUS_M_SLAR_NACK                   (0x48)
49 #define STATUS_M_RX_DATA_ACKED               (0x50)
50 #define STATUS_M_RX_DATA_NACKED              (0x58)
51 #define STATUS_S_SLAW_ACKED                  (0x60)
52 #define STATUS_S_ARB_LOST_SLAW_ACKED         (0x68)
53 #define STATUS_S_GENERAL_CALL_ACKED          (0x70)
54 #define STATUS_S_ARB_LOST_GENERAL_CALL_ACKED (0x78)
55 #define STATUS_S_RX_DATA_ACKED               (0x80)
56 #define STATUS_S_RX_DATA_NACKED              (0x88)
57 #define STATUS_S_GENERAL_CALL_RX_DATA_ACKED  (0x90)
58 #define STATUS_S_GENERAL_CALL_RX_DATA_NACKED (0x98)
59 #define STATUS_S_RX_STOP                     (0xA0)
60 #define STATUS_S_SLAR_ACKED                  (0xA8)
61 #define STATUS_S_ARB_LOST_SLAR_ACKED         (0xB0)
62 #define STATUS_S_TX_DATA_ACK                 (0xB8)
63 #define STATUS_S_TX_DATA_NACK                (0xC0)
64 #define STATUS_LAST_DATA_ACK                 (0xC8)
65 
66 #define PCLK_DIV_960 (CTRL_CR2)
67 #define PCLK_DIV_256 (0)
68 #define PCLK_DIV_224 (CTRL_CR0)
69 #define PCLK_DIV_192 (CTRL_CR1)
70 #define PCLK_DIV_160 (CTRL_CR0 | CTRL_CR1)
71 #define PCLK_DIV_120 (CTRL_CR0 | CTRL_CR2)
72 #define PCLK_DIV_60  (CTRL_CR1 | CTRL_CR2)
73 #define BCLK_DIV_8   (CTRL_CR0 | CTRL_CR1 | CTRL_CR2)
74 #define CLK_MASK     (CTRL_CR0 | CTRL_CR1 | CTRL_CR2)
75 
76 /* -- Transactions types -- */
77 #define NO_TRANSACTION                     (0x00)
78 #define CONTROLLER_WRITE_TRANSACTION       (0x01)
79 #define CONTROLLER_READ_TRANSACTION        (0x02)
80 #define CONTROLLER_RANDOM_READ_TRANSACTION (0x03)
81 #define WRITE_TARGET_TRANSACTION           (0x04)
82 #define READ_TARGET_TRANSACTION            (0x05)
83 
84 #define MSS_I2C_RELEASE_BUS (0x00)
85 #define MSS_I2C_HOLD_BUS    (0x01)
86 #define TARGET_ADDR_SHIFT   (0x01)
87 
88 #define MSS_I2C_SUCCESS     (0x00)
89 #define MSS_I2C_IN_PROGRESS (0x01)
90 #define MSS_I2C_FAILED      (0x02)
91 #define MSS_I2C_TIMED_OUT   (0x03)
92 
93 struct mss_i2c_config {
94 	uint32_t clock_freq;
95 	uintptr_t i2c_base_addr;
96 	uint32_t i2c_irq_base;
97 };
98 
99 struct mss_i2c_data {
100 	uint8_t ser_address;
101 	uint8_t target_addr;
102 	uint8_t options;
103 	uint8_t transaction;
104 	const uint8_t *controller_tx_buffer;
105 	uint16_t controller_tx_size;
106 	uint16_t controller_tx_idx;
107 	uint8_t dir;
108 	uint8_t *controller_rx_buffer;
109 	uint16_t controller_rx_size;
110 	uint16_t controller_rx_idx;
111 	atomic_t controller_status;
112 	uint32_t controller_timeout_ms;
113 	const uint8_t *target_tx_buffer;
114 	uint16_t target_tx_size;
115 	uint16_t target_tx_idx;
116 	uint8_t *target_rx_buffer;
117 	uint16_t target_rx_size;
118 	uint16_t target_rx_idx;
119 	atomic_t target_status;
120 	uint8_t target_mem_offset_length;
121 	uint8_t is_target_enabled;
122 	uint8_t bus_status;
123 	uint8_t is_transaction_pending;
124 	uint8_t pending_transaction;
125 
126 	sys_slist_t cb;
127 };
128 
129 
mss_i2c_configure(const struct device * dev,uint32_t dev_config_raw)130 static int mss_i2c_configure(const struct device *dev, uint32_t dev_config_raw)
131 {
132 	const struct mss_i2c_config *cfg = dev->config;
133 
134 	uint8_t ctrl = sys_read8(cfg->i2c_base_addr + CORE_I2C_CTRL);
135 
136 	switch (I2C_SPEED_GET(dev_config_raw)) {
137 	case I2C_SPEED_STANDARD:
138 		sys_write8((ctrl | PCLK_DIV_960), cfg->i2c_base_addr + CORE_I2C_CTRL);
139 		break;
140 	case I2C_SPEED_FAST:
141 		sys_write8((ctrl | PCLK_DIV_256), cfg->i2c_base_addr + CORE_I2C_CTRL);
142 		break;
143 	default:
144 		return -EINVAL;
145 	}
146 
147 	return 0;
148 }
149 
mss_wait_complete(const struct device * dev)150 static int mss_wait_complete(const struct device *dev)
151 {
152 	struct mss_i2c_data *const data = dev->data;
153 	atomic_t i2c_status = 0;
154 
155 	do {
156 		i2c_status = atomic_get(&data->controller_status);
157 	} while (i2c_status == MSS_I2C_IN_PROGRESS);
158 
159 	return i2c_status;
160 }
161 
mss_i2c_read(const struct device * dev,uint8_t serial_addr,uint8_t * read_buffer,uint32_t read_size)162 static int mss_i2c_read(const struct device *dev, uint8_t serial_addr, uint8_t *read_buffer,
163 			uint32_t read_size)
164 {
165 	struct mss_i2c_data *const data = dev->data;
166 	const struct mss_i2c_config *cfg = dev->config;
167 
168 	uint8_t ctrl = sys_read8(cfg->i2c_base_addr + CORE_I2C_CTRL);
169 
170 	data->target_addr = serial_addr << TARGET_ADDR_SHIFT;
171 	data->pending_transaction = CONTROLLER_READ_TRANSACTION;
172 	data->dir = I2C_MSG_READ;
173 	data->controller_rx_buffer = read_buffer;
174 	data->controller_rx_size = read_size;
175 	data->controller_rx_idx = 0u;
176 
177 	sys_write8((ctrl | CTRL_STA), cfg->i2c_base_addr + CORE_I2C_CTRL);
178 
179 	return 0;
180 }
181 
mss_i2c_write(const struct device * dev,uint8_t serial_addr,uint8_t * tx_buffer,uint32_t tx_num_write)182 static int mss_i2c_write(const struct device *dev, uint8_t serial_addr, uint8_t *tx_buffer,
183 			 uint32_t tx_num_write)
184 {
185 	struct mss_i2c_data *const data = dev->data;
186 	const struct mss_i2c_config *cfg = dev->config;
187 	uint8_t ctrl = sys_read8(cfg->i2c_base_addr + CORE_I2C_CTRL);
188 
189 	atomic_t target_status = data->target_status;
190 
191 	if (data->transaction == NO_TRANSACTION) {
192 		data->transaction = CONTROLLER_WRITE_TRANSACTION;
193 	}
194 
195 	data->pending_transaction = CONTROLLER_WRITE_TRANSACTION;
196 	data->target_addr = serial_addr << TARGET_ADDR_SHIFT;
197 	data->dir = I2C_MSG_WRITE;
198 	data->controller_tx_buffer = tx_buffer;
199 	data->controller_tx_size = tx_num_write;
200 	data->controller_tx_idx = 0u;
201 	atomic_set(&data->controller_status, MSS_I2C_IN_PROGRESS);
202 
203 	if (target_status == MSS_I2C_IN_PROGRESS) {
204 		data->is_transaction_pending = CONTROLLER_WRITE_TRANSACTION;
205 	} else {
206 		sys_write8((ctrl | CTRL_STA), cfg->i2c_base_addr + CORE_I2C_CTRL);
207 	}
208 
209 	if (data->bus_status == MSS_I2C_HOLD_BUS) {
210 		sys_write8((ctrl & ~CTRL_SI), cfg->i2c_base_addr + CORE_I2C_CTRL);
211 	}
212 
213 	return 0;
214 }
215 
216 
mss_i2c_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)217 static int mss_i2c_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs,
218 			    uint16_t addr)
219 {
220 	for (int i = 0; i < num_msgs; i++) {
221 		struct i2c_msg *current = &msgs[i];
222 
223 		if ((current->flags & I2C_MSG_RW_MASK) == I2C_MSG_READ) {
224 			mss_i2c_read(dev, addr, current->buf, current->len);
225 			mss_wait_complete(dev);
226 		} else {
227 			mss_i2c_write(dev, addr, current->buf, current->len);
228 			mss_wait_complete(dev);
229 		}
230 	}
231 
232 	return 0;
233 }
234 
235 static const struct i2c_driver_api mss_i2c_driver_api = {
236 	.configure = mss_i2c_configure,
237 	.transfer = mss_i2c_transfer,
238 };
239 
mss_i2c_reset(const struct device * dev)240 static void mss_i2c_reset(const struct device *dev)
241 {
242 	const struct mss_i2c_config *cfg = dev->config;
243 	uint8_t ctrl = sys_read8(cfg->i2c_base_addr + CORE_I2C_CTRL);
244 
245 	sys_write8((ctrl & ~CTRL_ENS1), cfg->i2c_base_addr + CORE_I2C_CTRL);
246 
247 	ctrl = sys_read8(cfg->i2c_base_addr + CORE_I2C_CTRL);
248 
249 	sys_write8((ctrl | CTRL_ENS1), cfg->i2c_base_addr + CORE_I2C_CTRL);
250 }
251 
252 
mss_i2c_irq_handler(const struct device * dev)253 static void mss_i2c_irq_handler(const struct device *dev)
254 {
255 	struct mss_i2c_data *const data = dev->data;
256 	const struct mss_i2c_config *cfg = dev->config;
257 
258 	uint8_t ctrl = sys_read8(cfg->i2c_base_addr + CORE_I2C_CTRL);
259 
260 	uint8_t status = sys_read8(cfg->i2c_base_addr + CORE_I2C_STATUS);
261 
262 	uint8_t hold_bus = 0;
263 
264 	switch (status) {
265 	case STATUS_M_START_SENT:
266 	case STATUS_M_REPEATED_START_SENT:
267 		sys_write8((ctrl & ~CTRL_STA), cfg->i2c_base_addr + CORE_I2C_CTRL);
268 
269 		sys_write8(data->target_addr | data->dir, cfg->i2c_base_addr + CORE_I2C_DATA);
270 
271 		data->controller_tx_idx = 0;
272 		data->controller_rx_idx = 0;
273 
274 		data->is_transaction_pending = false;
275 		data->transaction = data->pending_transaction;
276 		break;
277 	case STATUS_M_ARB_LOST:
278 		sys_write8((ctrl | CTRL_STA), cfg->i2c_base_addr + CORE_I2C_CTRL);
279 		LOG_WRN("lost arbitration: %x\n", status);
280 		break;
281 	case STATUS_M_SLAW_ACK:
282 	case STATUS_M_TX_DATA_ACK:
283 		if (data->controller_tx_idx < data->controller_tx_size) {
284 			sys_write8(data->controller_tx_buffer[data->controller_tx_idx],
285 				   cfg->i2c_base_addr + CORE_I2C_DATA);
286 
287 			data->controller_tx_idx++;
288 
289 		} else if (data->transaction == CONTROLLER_RANDOM_READ_TRANSACTION) {
290 			data->dir = I2C_MSG_READ;
291 			sys_write8((ctrl | CTRL_STA), cfg->i2c_base_addr + CORE_I2C_CTRL);
292 
293 		} else {
294 			data->transaction = NO_TRANSACTION;
295 			hold_bus = data->options & MSS_I2C_HOLD_BUS;
296 			data->bus_status = hold_bus;
297 
298 			if (hold_bus == MSS_I2C_RELEASE_BUS) {
299 				sys_write8((ctrl | CTRL_STO), cfg->i2c_base_addr + CORE_I2C_CTRL);
300 			}
301 		}
302 		atomic_set(&data->controller_status, MSS_I2C_SUCCESS);
303 		break;
304 	case STATUS_M_TX_DATA_NACK:
305 	case STATUS_M_SLAR_NACK:
306 	case STATUS_M_SLAW_NACK:
307 		sys_write8((ctrl | CTRL_STO), cfg->i2c_base_addr + CORE_I2C_CTRL);
308 		atomic_set(&data->controller_status, MSS_I2C_FAILED);
309 		data->transaction = NO_TRANSACTION;
310 		break;
311 	case STATUS_M_SLAR_ACK:
312 		if (data->controller_rx_size > 1u) {
313 			sys_write8((ctrl | CTRL_AA), cfg->i2c_base_addr + CORE_I2C_CTRL);
314 
315 		} else if (data->controller_rx_size == 1u) {
316 			sys_write8((ctrl & ~CTRL_AA), cfg->i2c_base_addr + CORE_I2C_CTRL);
317 
318 		} else {
319 			sys_write8((ctrl | CTRL_AA | CTRL_STO), cfg->i2c_base_addr + CORE_I2C_CTRL);
320 			atomic_set(&data->controller_status, MSS_I2C_SUCCESS);
321 			data->transaction = NO_TRANSACTION;
322 		}
323 		break;
324 	case STATUS_M_RX_DATA_ACKED:
325 		data->controller_rx_buffer[data->controller_rx_idx] =
326 			sys_read8(cfg->i2c_base_addr + CORE_I2C_DATA);
327 
328 		data->controller_rx_idx++;
329 
330 		/* Second Last byte */
331 		if (data->controller_rx_idx >= (data->controller_rx_size - 1u)) {
332 			sys_write8((ctrl & ~CTRL_AA), cfg->i2c_base_addr + CORE_I2C_CTRL);
333 		} else {
334 			atomic_set(&data->controller_status, MSS_I2C_IN_PROGRESS);
335 		}
336 		break;
337 	case STATUS_M_RX_DATA_NACKED:
338 
339 		data->controller_rx_buffer[data->controller_rx_idx] =
340 			sys_read8(cfg->i2c_base_addr + CORE_I2C_DATA);
341 
342 		hold_bus = data->options & MSS_I2C_HOLD_BUS;
343 		data->bus_status = hold_bus;
344 
345 		if (hold_bus == 0u) {
346 			sys_write8((ctrl | CTRL_STO), cfg->i2c_base_addr + CORE_I2C_CTRL);
347 		}
348 
349 		data->transaction = NO_TRANSACTION;
350 		atomic_set(&data->controller_status, MSS_I2C_SUCCESS);
351 		break;
352 	default:
353 		break;
354 	}
355 
356 	ctrl = sys_read8(cfg->i2c_base_addr + CORE_I2C_CTRL);
357 
358 	sys_write8((ctrl & ~CTRL_SI), cfg->i2c_base_addr + CORE_I2C_CTRL);
359 }
360 
361 #define MSS_I2C_INIT(n)                                                                            \
362 	static int mss_i2c_init_##n(const struct device *dev)                                      \
363 	{                                                                                          \
364 		mss_i2c_reset(dev);                                                                \
365                                                                                                    \
366 		IRQ_CONNECT(DT_INST_IRQN(n), DT_INST_IRQ(n, priority), mss_i2c_irq_handler,        \
367 			    DEVICE_DT_INST_GET(n), 0);                                             \
368                                                                                                    \
369 		irq_enable(DT_INST_IRQN(n));                                                       \
370                                                                                                    \
371 		return 0;                                                                          \
372 	}                                                                                          \
373                                                                                                    \
374 	static struct mss_i2c_data mss_i2c_data_##n;                                               \
375                                                                                                    \
376 	static const struct mss_i2c_config mss_i2c_config_##n = {                                  \
377 		.i2c_base_addr = DT_INST_REG_ADDR(n),                                              \
378 		.i2c_irq_base = DT_INST_IRQN(n),                                                   \
379 		.clock_freq = DT_INST_PROP(n, clock_frequency),                                    \
380 	};                                                                                         \
381                                                                                                    \
382 	DEVICE_DT_INST_DEFINE(n, mss_i2c_init_##n, NULL, &mss_i2c_data_##n, &mss_i2c_config_##n,   \
383 			      PRE_KERNEL_1, CONFIG_I2C_INIT_PRIORITY, &mss_i2c_driver_api);
384 
385 DT_INST_FOREACH_STATUS_OKAY(MSS_I2C_INIT)
386