1 /*
2 * Copyright (c) 2024 Renesas Electronics Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #define DT_DRV_COMPAT renesas_ra_iic
8
9 #include <math.h>
10 #include <zephyr/devicetree.h>
11 #include <zephyr/drivers/clock_control.h>
12 #include <zephyr/drivers/i2c.h>
13 #include <zephyr/drivers/pinctrl.h>
14 #include <zephyr/irq.h>
15 #include <zephyr/sys/util.h>
16
17 #include "r_iic_master.h"
18 #include <errno.h>
19 #include <soc.h>
20
21 #include <zephyr/logging/log.h>
22 LOG_MODULE_REGISTER(renesas_ra_iic);
23
24 typedef void (*init_func_t)(const struct device *dev);
25 static const double RA_IIC_MASTER_DIV_TIME_NS = 1000000000;
26
27 struct i2c_ra_iic_config {
28 void (*irq_config_func)(const struct device *dev);
29 const struct pinctrl_dev_config *pcfg;
30 uint32_t noise_filter_stage;
31 double rise_time_s;
32 double fall_time_s;
33 uint32_t duty_cycle_percent;
34 };
35
36 struct i2c_ra_iic_data {
37 iic_master_instance_ctrl_t ctrl;
38 i2c_master_cfg_t fsp_config;
39 struct k_mutex bus_mutex;
40 struct k_sem complete_sem;
41 i2c_master_event_t event;
42 iic_master_extended_cfg_t iic_master_ext_cfg;
43 uint32_t dev_config;
44 };
45
46 /* IIC master clock setting calculation function. */
47 static void calc_iic_master_clock_setting(const struct device *dev, const uint32_t fsp_i2c_rate,
48 iic_master_clock_settings_t *clk_cfg);
49
50 /* FSP interruption handlers. */
51 void iic_master_rxi_isr(void);
52 void iic_master_txi_isr(void);
53 void iic_master_tei_isr(void);
54 void iic_master_eri_isr(void);
55
56 struct ra_iic_master_bitrate {
57 uint32_t bitrate;
58 uint32_t duty;
59 uint32_t divider;
60 uint32_t brl;
61 uint32_t brh;
62 uint32_t duty_error_percent;
63 };
64
i2c_ra_iic_configure(const struct device * dev,uint32_t dev_config)65 static int i2c_ra_iic_configure(const struct device *dev, uint32_t dev_config)
66 {
67 struct i2c_ra_iic_data *data = (struct i2c_ra_iic_data *const)dev->data;
68
69 if (!(dev_config & I2C_MODE_CONTROLLER)) {
70 LOG_ERR("Only I2C Master mode supported.");
71 return -EIO;
72 }
73
74 switch (I2C_SPEED_GET(dev_config)) {
75 case I2C_SPEED_STANDARD:
76 data->fsp_config.rate = I2C_MASTER_RATE_STANDARD;
77 break;
78 case I2C_SPEED_FAST:
79 data->fsp_config.rate = I2C_MASTER_RATE_FAST;
80 break;
81 case I2C_SPEED_FAST_PLUS:
82 data->fsp_config.rate = I2C_MASTER_RATE_FASTPLUS;
83 break;
84 default:
85 LOG_ERR("%s: Invalid I2C speed rate flag: %d", __func__, I2C_SPEED_GET(dev_config));
86 return -EIO;
87 }
88
89 /* Recalc clock setting after updating config. */
90 calc_iic_master_clock_setting(dev, data->fsp_config.rate,
91 &data->iic_master_ext_cfg.clock_settings);
92
93 R_IIC_MASTER_Close(&data->ctrl);
94 R_IIC_MASTER_Open(&data->ctrl, &data->fsp_config);
95
96 /* save current devconfig. */
97 data->dev_config = dev_config;
98
99 return 0;
100 }
101
i2c_ra_iic_get_config(const struct device * dev,uint32_t * dev_config)102 static int i2c_ra_iic_get_config(const struct device *dev, uint32_t *dev_config)
103 {
104 struct i2c_ra_iic_data *data = (struct i2c_ra_iic_data *const)dev->data;
105 *dev_config = data->dev_config;
106
107 return 0;
108 }
109
110 #define OPERATION(msg) (((struct i2c_msg *)msg)->flags & I2C_MSG_RW_MASK)
111
i2c_ra_iic_transfer(const struct device * dev,struct i2c_msg * msgs,uint8_t num_msgs,uint16_t addr)112 static int i2c_ra_iic_transfer(const struct device *dev, struct i2c_msg *msgs, uint8_t num_msgs,
113 uint16_t addr)
114 {
115 struct i2c_ra_iic_data *data = (struct i2c_ra_iic_data *const)dev->data;
116 struct i2c_msg *current, *next;
117 fsp_err_t fsp_err = FSP_SUCCESS;
118 int ret = 0;
119
120 if (!num_msgs) {
121 return 0;
122 }
123
124 /* Check for validity of all messages before transfer */
125 current = msgs;
126
127 /*
128 * Set I2C_MSG_RESTART flag on first message in order to send start
129 * condition
130 */
131 current->flags |= I2C_MSG_RESTART;
132
133 for (int i = 1; i <= num_msgs; i++) {
134 if (i < num_msgs) {
135 next = current + 1;
136
137 /*
138 * Restart condition between messages
139 * of different directions is required
140 */
141 if (OPERATION(current) != OPERATION(next)) {
142 if (!(next->flags & I2C_MSG_RESTART)) {
143 LOG_ERR("%s: Restart condition between messages of "
144 "different directions is required."
145 "Current/Total: [%d/%d]",
146 __func__, i, num_msgs);
147 ret = -EIO;
148 break;
149 }
150 }
151
152 /* Stop condition is only allowed on last message */
153 if (current->flags & I2C_MSG_STOP) {
154 LOG_ERR("%s: Invalid stop flag. Stop condition is only allowed on "
155 "last message. "
156 "Current/Total: [%d/%d]",
157 __func__, i, num_msgs);
158 ret = -EIO;
159 break;
160 }
161 } else {
162 current->flags |= I2C_MSG_STOP;
163 }
164
165 current++;
166 }
167
168 if (ret) {
169 return ret;
170 }
171
172 k_mutex_lock(&data->bus_mutex, K_FOREVER);
173
174 /* Set destination address with configured address mode before sending msg. */
175
176 i2c_master_addr_mode_t addr_mode = 0;
177
178 if (I2C_MSG_ADDR_10_BITS & data->dev_config) {
179 addr_mode = I2C_MASTER_ADDR_MODE_10BIT;
180 } else {
181 addr_mode = I2C_MASTER_ADDR_MODE_7BIT;
182 }
183
184 R_IIC_MASTER_SlaveAddressSet(&data->ctrl, addr, addr_mode);
185
186 /* Process input `msgs`. */
187
188 current = msgs;
189
190 while (num_msgs > 0) {
191 if (num_msgs > 1) {
192 next = current + 1;
193 } else {
194 next = NULL;
195 }
196
197 if (current->flags & I2C_MSG_READ) {
198 fsp_err =
199 R_IIC_MASTER_Read(&data->ctrl, current->buf, current->len,
200 next != NULL && (next->flags & I2C_MSG_RESTART));
201 } else {
202 fsp_err =
203 R_IIC_MASTER_Write(&data->ctrl, current->buf, current->len,
204 next != NULL && (next->flags & I2C_MSG_RESTART));
205 }
206
207 if (fsp_err != FSP_SUCCESS) {
208 switch (fsp_err) {
209 case FSP_ERR_INVALID_SIZE:
210 LOG_ERR("%s: Provided number of bytes more than uint16_t size "
211 "(65535) while DTC is used for data transfer.",
212 __func__);
213 break;
214 case FSP_ERR_IN_USE:
215 LOG_ERR("%s: Bus busy condition. Another transfer was in progress.",
216 __func__);
217 break;
218 default:
219 /* Should not reach here. */
220 LOG_ERR("%s: Unknown error. FSP_ERR=%d\n", __func__, fsp_err);
221 break;
222 }
223
224 ret = -EIO;
225 goto RELEASE_BUS;
226 }
227
228 /* Wait for callback to return. */
229 k_sem_take(&data->complete_sem, K_FOREVER);
230
231 /* Handle event msg from callback. */
232 switch (data->event) {
233 case I2C_MASTER_EVENT_ABORTED:
234 LOG_ERR("%s: %s failed.", __func__,
235 (current->flags & I2C_MSG_READ) ? "Read" : "Write");
236 ret = -EIO;
237 goto RELEASE_BUS;
238 case I2C_MASTER_EVENT_RX_COMPLETE:
239 break;
240 case I2C_MASTER_EVENT_TX_COMPLETE:
241 break;
242 default:
243 break;
244 }
245
246 current++;
247 num_msgs--;
248 }
249
250 RELEASE_BUS:
251 k_mutex_unlock(&data->bus_mutex);
252
253 return ret;
254 }
255
i2c_ra_iic_callback(i2c_master_callback_args_t * p_args)256 static void i2c_ra_iic_callback(i2c_master_callback_args_t *p_args)
257 {
258 const struct device *dev = p_args->p_context;
259 struct i2c_ra_iic_data *data = dev->data;
260
261 data->event = p_args->event;
262
263 k_sem_give(&data->complete_sem);
264 }
265
i2c_ra_iic_init(const struct device * dev)266 static int i2c_ra_iic_init(const struct device *dev)
267 {
268 const struct i2c_ra_iic_config *config = dev->config;
269 struct i2c_ra_iic_data *data = (struct i2c_ra_iic_data *)dev->data;
270 fsp_err_t fsp_err = FSP_SUCCESS;
271 int ret = 0;
272
273 /* Configure dt provided device signals when available */
274 ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT);
275
276 if (ret < 0) {
277 LOG_ERR("%s: pinctrl config failed.", __func__);
278 return ret;
279 }
280
281 k_mutex_init(&data->bus_mutex);
282 k_sem_init(&data->complete_sem, 0, 1);
283
284 switch (data->fsp_config.rate) {
285 case I2C_MASTER_RATE_STANDARD:
286 case I2C_MASTER_RATE_FAST:
287 case I2C_MASTER_RATE_FASTPLUS:
288 calc_iic_master_clock_setting(dev, data->fsp_config.rate,
289 &data->iic_master_ext_cfg.clock_settings);
290 data->iic_master_ext_cfg.timeout_mode = IIC_MASTER_TIMEOUT_MODE_SHORT;
291 data->iic_master_ext_cfg.timeout_scl_low = IIC_MASTER_TIMEOUT_SCL_LOW_ENABLED;
292
293 data->fsp_config.p_extend = &data->iic_master_ext_cfg;
294 break;
295 default:
296 LOG_ERR("%s: Invalid I2C speed rate: %d", __func__, data->fsp_config.rate);
297 return -ENOTSUP;
298 }
299
300 fsp_err = R_IIC_MASTER_Open(&data->ctrl, &data->fsp_config);
301 __ASSERT(fsp_err == FSP_SUCCESS, "%s: Open iic master failed. FSP_ERR=%d", __func__,
302 fsp_err);
303
304 config->irq_config_func(dev);
305
306 return 0;
307 }
308
calc_iic_master_bitrate(const struct i2c_ra_iic_config * config,uint32_t total_brl_brh,uint32_t brh,uint32_t divider,struct ra_iic_master_bitrate * result)309 static void calc_iic_master_bitrate(const struct i2c_ra_iic_config *config, uint32_t total_brl_brh,
310 uint32_t brh, uint32_t divider,
311 struct ra_iic_master_bitrate *result)
312 {
313 const uint32_t noise_filter_stage = config->noise_filter_stage;
314 const double rise_time_s = config->rise_time_s;
315 const double fall_time_s = config->fall_time_s;
316 const uint32_t requested_duty = config->duty_cycle_percent;
317 const uint32_t peripheral_clock = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_PCLKB);
318 uint32_t constant_add = 0;
319
320 /* A constant is added to BRL and BRH in all formulas. This constand is 3 + nf
321 * when CKS == 0, or 2 + nf when CKS != 0.
322 */
323 if (divider == 0) {
324 constant_add = 3 + noise_filter_stage;
325 } else {
326 /* All dividers other than 0 use an addition of 2 + noise_filter_stages. */
327 constant_add = 2 + noise_filter_stage;
328 }
329
330 /* Converts all divided numbers to double to avoid data loss. */
331 uint32_t divided_pclk = (peripheral_clock >> divider);
332
333 result->bitrate =
334 1 / ((total_brl_brh + 2 * constant_add) / divided_pclk + rise_time_s + fall_time_s);
335 result->duty =
336 100 *
337 ((rise_time_s + ((brh + constant_add) / divided_pclk)) /
338 (rise_time_s + fall_time_s + ((total_brl_brh + 2 * constant_add)) / divided_pclk));
339 result->divider = divider;
340 result->brh = brh;
341 result->brl = total_brl_brh - brh;
342 result->duty_error_percent =
343 (result->duty > requested_duty ? result->duty - requested_duty
344 : requested_duty - result->duty) /
345 requested_duty;
346
347 LOG_DBG("%s: [input] total_brl_brh[%d] brh[%d] divider[%d]"
348 " [output] bitrate[%u] duty[%u] divider[%u] brh[%u] brl[%u] "
349 "duty_error_percent[%u]\n",
350 __func__, total_brl_brh, brh, divider, result->bitrate, result->duty,
351 result->divider, result->brh, result->brl, result->duty_error_percent);
352 }
353
calc_iic_master_clock_setting(const struct device * dev,const uint32_t fsp_i2c_rate,iic_master_clock_settings_t * clk_cfg)354 static void calc_iic_master_clock_setting(const struct device *dev, const uint32_t fsp_i2c_rate,
355 iic_master_clock_settings_t *clk_cfg)
356 {
357 const struct i2c_ra_iic_config *config = dev->config;
358 const uint32_t noise_filter_stage = config->noise_filter_stage;
359 const double rise_time_s = config->rise_time_s;
360 const double fall_time_s = config->fall_time_s;
361 const uint32_t requested_duty = config->duty_cycle_percent;
362 const uint32_t peripheral_clock = R_FSP_SystemClockHzGet(FSP_PRIV_CLOCK_PCLKB);
363
364 uint32_t requested_bitrate = 0;
365
366 switch (fsp_i2c_rate) {
367 case I2C_MASTER_RATE_STANDARD:
368 case I2C_MASTER_RATE_FAST:
369 case I2C_MASTER_RATE_FASTPLUS:
370 requested_bitrate = fsp_i2c_rate;
371 break;
372 default:
373 LOG_ERR("%s: Invalid I2C speed rate: %d", __func__, fsp_i2c_rate);
374 return;
375 }
376
377 /* Start with maximum possible bitrate. */
378 uint32_t min_brh = noise_filter_stage + 1;
379 uint32_t min_brl_brh = 2 * min_brh;
380 struct ra_iic_master_bitrate bitrate = {};
381
382 calc_iic_master_bitrate(config, min_brl_brh, min_brh, 0, &bitrate);
383
384 /* Start with the smallest divider because it gives the most resolution. */
385 uint32_t constant_add = 3 + noise_filter_stage;
386
387 for (int temp_divider = 0; temp_divider <= 7; ++temp_divider) {
388 if (1 == temp_divider) {
389 /* All dividers other than 0 use an addition of 2 + noise_filter_stages.
390 */
391 constant_add = 2 + noise_filter_stage;
392 }
393
394 /* If the requested bitrate cannot be achieved with this divider, continue.
395 */
396 uint32_t divided_pclk = (peripheral_clock >> temp_divider);
397 uint32_t total_brl_brh =
398 ceil(((1 / (double)requested_bitrate) - (rise_time_s + fall_time_s)) *
399 divided_pclk -
400 (2 * constant_add));
401
402 if ((total_brl_brh > 62) || (total_brl_brh < min_brl_brh)) {
403 continue;
404 }
405
406 uint32_t temp_brh = total_brl_brh * requested_duty / 100;
407
408 if (temp_brh < min_brh) {
409 temp_brh = min_brh;
410 }
411
412 /* Calculate the actual bitrate and duty cycle. */
413 struct ra_iic_master_bitrate temp_bitrate = {};
414
415 calc_iic_master_bitrate(config, total_brl_brh, temp_brh, temp_divider,
416 &temp_bitrate);
417
418 /* Adjust duty cycle down if it helps. */
419 struct ra_iic_master_bitrate test_bitrate = temp_bitrate;
420
421 while (test_bitrate.duty > requested_duty) {
422 temp_brh -= 1;
423
424 if ((temp_brh < min_brh) || ((total_brl_brh - temp_brh) > 31)) {
425 break;
426 }
427
428 struct ra_iic_master_bitrate new_bitrate = {};
429
430 calc_iic_master_bitrate(config, total_brl_brh, temp_brh, temp_divider,
431 &new_bitrate);
432
433 if (new_bitrate.duty_error_percent < temp_bitrate.duty_error_percent) {
434 temp_bitrate = new_bitrate;
435 } else {
436 break;
437 }
438 }
439
440 /* Adjust duty cycle up if it helps. */
441 while (test_bitrate.duty < requested_duty) {
442 ++temp_brh;
443
444 if ((temp_brh > total_brl_brh) || (temp_brh > 31) ||
445 ((total_brl_brh - temp_brh) < min_brh)) {
446 break;
447 }
448
449 struct ra_iic_master_bitrate new_bitrate = {};
450
451 calc_iic_master_bitrate(config, total_brl_brh, temp_brh, temp_divider,
452 &new_bitrate);
453
454 if (new_bitrate.duty_error_percent < temp_bitrate.duty_error_percent) {
455 temp_bitrate = new_bitrate;
456 } else {
457 break;
458 }
459 }
460
461 if ((temp_bitrate.brh < 32) && (temp_bitrate.brl < 32)) {
462 /* Valid setting found. */
463 bitrate = temp_bitrate;
464 break;
465 }
466 }
467
468 clk_cfg->brl_value = bitrate.brl;
469 clk_cfg->brh_value = bitrate.brh;
470 clk_cfg->cks_value = bitrate.divider;
471
472 LOG_DBG("%s: [input] rate[%u] [output] brl[%u] brh[%u] cks[%u]\n", __func__, fsp_i2c_rate,
473 clk_cfg->brl_value, clk_cfg->brh_value, clk_cfg->cks_value);
474 }
475
476 static DEVICE_API(i2c, i2c_ra_iic_driver_api) = {
477 .configure = i2c_ra_iic_configure,
478 .get_config = i2c_ra_iic_get_config,
479 .transfer = i2c_ra_iic_transfer,
480 };
481
482 #define _ELC_EVENT_IIC_RXI(channel) ELC_EVENT_IIC##channel##_RXI
483 #define _ELC_EVENT_IIC_TXI(channel) ELC_EVENT_IIC##channel##_TXI
484 #define _ELC_EVENT_IIC_TEI(channel) ELC_EVENT_IIC##channel##_TEI
485 #define _ELC_EVENT_IIC_ERI(channel) ELC_EVENT_IIC##channel##_ERI
486
487 #define ELC_EVENT_IIC_RXI(channel) _ELC_EVENT_IIC_RXI(channel)
488 #define ELC_EVENT_IIC_TXI(channel) _ELC_EVENT_IIC_TXI(channel)
489 #define ELC_EVENT_IIC_TEI(channel) _ELC_EVENT_IIC_TEI(channel)
490 #define ELC_EVENT_IIC_ERI(channel) _ELC_EVENT_IIC_ERI(channel)
491
492 #define I2C_RA_IIC_INIT(index) \
493 \
494 PINCTRL_DT_INST_DEFINE(index); \
495 \
496 static void i2c_ra_iic_irq_config_func##index(const struct device *dev) \
497 { \
498 R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, rxi, irq)] = \
499 ELC_EVENT_IIC_RXI(DT_INST_PROP(index, channel)); \
500 R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, txi, irq)] = \
501 ELC_EVENT_IIC_TXI(DT_INST_PROP(index, channel)); \
502 R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, tei, irq)] = \
503 ELC_EVENT_IIC_TEI(DT_INST_PROP(index, channel)); \
504 R_ICU->IELSR[DT_INST_IRQ_BY_NAME(index, eri, irq)] = \
505 ELC_EVENT_IIC_ERI(DT_INST_PROP(index, channel)); \
506 \
507 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, rxi, irq), \
508 DT_INST_IRQ_BY_NAME(index, rxi, priority), iic_master_rxi_isr, \
509 DEVICE_DT_INST_GET(index), 0); \
510 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, txi, irq), \
511 DT_INST_IRQ_BY_NAME(index, txi, priority), iic_master_txi_isr, \
512 DEVICE_DT_INST_GET(index), 0); \
513 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, tei, irq), \
514 DT_INST_IRQ_BY_NAME(index, tei, priority), iic_master_tei_isr, \
515 DEVICE_DT_INST_GET(index), 0); \
516 IRQ_CONNECT(DT_INST_IRQ_BY_NAME(index, eri, irq), \
517 DT_INST_IRQ_BY_NAME(index, eri, priority), iic_master_eri_isr, \
518 DEVICE_DT_INST_GET(index), 0); \
519 \
520 irq_enable(DT_INST_IRQ_BY_NAME(index, rxi, irq)); \
521 irq_enable(DT_INST_IRQ_BY_NAME(index, txi, irq)); \
522 irq_enable(DT_INST_IRQ_BY_NAME(index, tei, irq)); \
523 irq_enable(DT_INST_IRQ_BY_NAME(index, eri, irq)); \
524 } \
525 \
526 static const struct i2c_ra_iic_config i2c_ra_iic_config_##index = { \
527 .pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(index), \
528 .irq_config_func = i2c_ra_iic_irq_config_func##index, \
529 .noise_filter_stage = 1, /* Cannot be configured. */ \
530 .rise_time_s = DT_INST_PROP(index, rise_time_ns) / RA_IIC_MASTER_DIV_TIME_NS, \
531 .fall_time_s = DT_INST_PROP(index, fall_time_ns) / RA_IIC_MASTER_DIV_TIME_NS, \
532 .duty_cycle_percent = DT_INST_PROP(index, duty_cycle_percent), \
533 }; \
534 \
535 static struct i2c_ra_iic_data i2c_ra_iic_data_##index = { \
536 .fsp_config = \
537 { \
538 .channel = DT_INST_PROP(index, channel), \
539 .slave = 0, \
540 .rate = DT_INST_PROP(index, clock_frequency), \
541 .addr_mode = I2C_MASTER_ADDR_MODE_7BIT, \
542 .ipl = DT_INST_PROP(index, interrupt_priority_level), \
543 .rxi_irq = DT_INST_IRQ_BY_NAME(index, rxi, irq), \
544 .txi_irq = DT_INST_IRQ_BY_NAME(index, txi, irq), \
545 .tei_irq = DT_INST_IRQ_BY_NAME(index, tei, irq), \
546 .eri_irq = DT_INST_IRQ_BY_NAME(index, eri, irq), \
547 .p_callback = i2c_ra_iic_callback, \
548 .p_context = DEVICE_DT_GET(DT_DRV_INST(index)), \
549 }, \
550 }; \
551 \
552 I2C_DEVICE_DT_INST_DEFINE(index, i2c_ra_iic_init, NULL, &i2c_ra_iic_data_##index, \
553 &i2c_ra_iic_config_##index, POST_KERNEL, \
554 CONFIG_I2C_INIT_PRIORITY, &i2c_ra_iic_driver_api);
555
556 DT_INST_FOREACH_STATUS_OKAY(I2C_RA_IIC_INIT)
557