From c536e522387d56c9e70eef3bc57c7b6cdef7126e Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Mon, 29 Sep 2025 11:38:23 +0700 Subject: [PATCH 1/6] drivers: i2c: Initial support for i2c sci driver on Renesas RA First commit to add support for Renesas RA i2c sci driver Signed-off-by: Khai Cao --- drivers/i2c/CMakeLists.txt | 1 + drivers/i2c/Kconfig.renesas_ra | 19 + drivers/i2c/i2c_renesas_ra_sci.c | 731 +++++++++++++++++++++++ dts/bindings/i2c/renesas,ra-i2c-sci.yaml | 34 ++ modules/Kconfig.renesas | 5 + 5 files changed, 790 insertions(+) create mode 100644 drivers/i2c/i2c_renesas_ra_sci.c create mode 100644 dts/bindings/i2c/renesas,ra-i2c-sci.yaml diff --git a/drivers/i2c/CMakeLists.txt b/drivers/i2c/CMakeLists.txt index 6fdb72b57e7b3..c8f93aa897bbc 100644 --- a/drivers/i2c/CMakeLists.txt +++ b/drivers/i2c/CMakeLists.txt @@ -56,6 +56,7 @@ zephyr_library_sources_ifdef(CONFIG_I2C_NXP_II2C i2c_nxp_ii2c.c) zephyr_library_sources_ifdef(CONFIG_I2C_OMAP i2c_omap.c) zephyr_library_sources_ifdef(CONFIG_I2C_RCAR i2c_rcar.c) zephyr_library_sources_ifdef(CONFIG_I2C_RENESAS_RA_IIC i2c_renesas_ra_iic.c) +zephyr_library_sources_ifdef(CONFIG_I2C_RENESAS_RA_SCI i2c_renesas_ra_sci.c) zephyr_library_sources_ifdef(CONFIG_I2C_RENESAS_RA_SCI_B i2c_renesas_ra_sci_b.c) zephyr_library_sources_ifdef(CONFIG_I2C_RENESAS_RX_RIIC i2c_renesas_rx_riic.c) zephyr_library_sources_ifdef(CONFIG_I2C_RENESAS_RZ_IIC i2c_renesas_rz_riic.c) diff --git a/drivers/i2c/Kconfig.renesas_ra b/drivers/i2c/Kconfig.renesas_ra index 4a64daf5b42e6..0c2c86f46d844 100644 --- a/drivers/i2c/Kconfig.renesas_ra +++ b/drivers/i2c/Kconfig.renesas_ra @@ -12,6 +12,25 @@ config I2C_RENESAS_RA_IIC help Enable Renesas RA I2C IIC Driver. +config I2C_RENESAS_RA_SCI + bool "Renesas RA SCI I2C" + default y + depends on DT_HAS_RENESAS_RA_I2C_SCI_ENABLED + select USE_RA_FSP_SCI_I2C + select PINCTRL + help + Enable Renesas RA SCI I2C Driver. + +if I2C_RENESAS_RA_SCI +config I2C_RENESAS_RA_SCI_DTC + bool "DTC on Transmission and Reception" + default y + select USE_RA_FSP_DTC + help + Enable DTC on transmission and reception + +endif + config I2C_RENESAS_RA_SCI_B bool "Renesas RA SCI-B I2C" default y diff --git a/drivers/i2c/i2c_renesas_ra_sci.c b/drivers/i2c/i2c_renesas_ra_sci.c new file mode 100644 index 0000000000000..c61a0ef2c901b --- /dev/null +++ b/drivers/i2c/i2c_renesas_ra_sci.c @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +#define DT_DRV_COMPAT renesas_ra_i2c_sci + +#define MDDR_DISABLE 256 + +#include +#include +#include +#include +#include +#include +#include + +#include "r_sci_i2c.h" +#ifdef CONFIG_I2C_RENESAS_RA_SCI_DTC +#include "r_dtc.h" +#endif + +#include + +LOG_MODULE_REGISTER(renesas_ra_i2c_sci, CONFIG_I2C_LOG_LEVEL); + +#define I2C_MAX_MSG_LEN (1 << (sizeof(uint8_t) * 8)) + +typedef void (*init_func_t)(const struct device *dev); +struct sci_i2c_config { + void (*irq_config_func)(const struct device *dev); + const struct pinctrl_dev_config *pcfg; + uint16_t sda_output_delay; +}; + +struct sci_i2c_data { + sci_i2c_instance_ctrl_t ctrl; + i2c_master_cfg_t i2c_config; + sci_i2c_extended_cfg_t ext_cfg; + struct k_sem bus_lock; + struct k_sem complete_sem; + i2c_master_event_t event; + uint32_t dev_config; + +#ifdef CONFIG_I2C_CALLBACK + uint16_t addr; + uint32_t msg_idx; + struct i2c_msg *msgs; + uint32_t num_msgs; + i2c_callback_t cb; + void *p_context; +#endif /* CONFIG_I2C_CALLBACK */ + +#ifdef CONFIG_I2C_RENESAS_RA_SCI_DTC + /* RX */ + transfer_instance_t rx_transfer; + + transfer_info_t rx_transfer_info DTC_TRANSFER_INFO_ALIGNMENT; + + transfer_cfg_t rx_transfer_cfg; + dtc_instance_ctrl_t rx_transfer_ctrl; + dtc_extended_cfg_t rx_transfer_cfg_extend; + + /* TX */ + transfer_instance_t tx_transfer; + + transfer_info_t tx_transfer_info DTC_TRANSFER_INFO_ALIGNMENT; + + transfer_cfg_t tx_transfer_cfg; + dtc_instance_ctrl_t tx_transfer_ctrl; + dtc_extended_cfg_t tx_transfer_cfg_extend; +#endif /* CONFIG_I2C_RENESAS_RA_SCI_DTC */ +}; + +static void calc_sci_iic_clock_setting(const struct device *dev, const uint32_t fsp_i2c_rate, + sci_i2c_clock_settings_t *clk_cfg); + +/* FSP interruption handlers. */ +void sci_i2c_txi_isr(void); +void sci_i2c_tei_isr(void); +void sci_i2c_rxi_isr(void); + +static int renesas_ra_sci_i2c_configure(const struct device *dev, uint32_t dev_config) +{ + struct sci_i2c_data *data = (struct sci_i2c_data *const)dev->data; + + if (!(dev_config & I2C_MODE_CONTROLLER)) { + LOG_ERR("Only I2C Master mode supported."); + return -EIO; + } + + switch (I2C_SPEED_GET(dev_config)) { + case I2C_SPEED_STANDARD: + data->i2c_config.rate = I2C_MASTER_RATE_STANDARD; + break; + case I2C_SPEED_FAST: + data->i2c_config.rate = I2C_MASTER_RATE_FAST; + break; + default: + LOG_ERR("Invalid I2C speed rate flag: %d", I2C_SPEED_GET(dev_config)); + return -EIO; + } + + calc_sci_iic_clock_setting(dev, data->i2c_config.rate, &data->ext_cfg.clock_settings); + + R_SCI_I2C_Close(&data->ctrl); + R_SCI_I2C_Open(&data->ctrl, &data->i2c_config); + + /* save current devconfig. */ + data->dev_config = dev_config; + + return 0; +} + +static int renesas_ra_sci_i2c_get_config(const struct device *dev, uint32_t *dev_config) +{ + struct sci_i2c_data *data = (struct sci_i2c_data *const)dev->data; + *dev_config = data->dev_config; + return 0; +} + +#define OPERATION(msg) (((struct i2c_msg *)msg)->flags & I2C_MSG_RW_MASK) + +static int renesas_ra_sci_i2c_transfer(const struct device *dev, struct i2c_msg *msgs, + uint8_t num_msgs, uint16_t addr) +{ + struct sci_i2c_data *data = (struct sci_i2c_data *const)dev->data; + struct i2c_msg *current, *next; + fsp_err_t fsp_err; + int ret; + + if (!num_msgs) { + return 0; + } + + /* Handle i2c burst write, restructure message to be compatible with HAL*/ + if (num_msgs == 2) { + if (msgs[0].len == 1U && !(msgs[0].flags & I2C_MSG_READ) && + !(msgs[1].flags & I2C_MSG_READ)) { + uint16_t tmp_len = msgs[0].len + msgs[1].len; + + if (tmp_len <= I2C_MAX_MSG_LEN) { + static uint8_t merge_buf[I2C_MAX_MSG_LEN]; + struct i2c_msg tmp_msg; + + memcpy(&merge_buf[0], msgs[0].buf, msgs[0].len); + memcpy(&merge_buf[msgs[0].len], msgs[1].buf, msgs[1].len); + tmp_msg.buf = &merge_buf[0]; + tmp_msg.flags = I2C_MSG_WRITE | I2C_MSG_STOP; + tmp_msg.len = (uint8_t)tmp_len; + /* Merge 2 msgs into 1 msg */ + msgs[0] = tmp_msg; + num_msgs = 1; + } else { + LOG_DBG("messages are too large to merge"); + } + } + } + + current = msgs; + ret = 0; + + /* Check for validity of all messages before transfer */ + for (int i = 1; i <= num_msgs; i++) { + if (i < num_msgs) { + next = current + 1; + + /* + * Restart condition between messages + * of different directions is required + */ + if (OPERATION(current) != OPERATION(next)) { + if (!(next->flags & I2C_MSG_RESTART)) { + LOG_ERR("Restart condition between messages of " + "different directions is required." + "Current/Total: [%d/%d]", + i, num_msgs); + ret = -EIO; + break; + } + } + + /* Stop condition is only allowed on last message */ + if (current->flags & I2C_MSG_STOP) { + LOG_ERR("Invalid stop flag. Stop condition is only allowed on " + "last message. " + "Current/Total: [%d/%d]", + i, num_msgs); + ret = -EIO; + break; + } + } else { + current->flags |= I2C_MSG_STOP; + } + + current++; + } + + if (ret) { + return ret; + } + + k_sem_take(&data->bus_lock, K_FOREVER); + + /* Set destination address with configured address mode before sending msg. */ + + i2c_master_addr_mode_t addr_mode = 0; + + if (I2C_MSG_ADDR_10_BITS & data->dev_config) { + addr_mode = I2C_MASTER_ADDR_MODE_10BIT; + } else { + addr_mode = I2C_MASTER_ADDR_MODE_7BIT; + } + + R_SCI_I2C_SlaveAddressSet(&data->ctrl, addr, addr_mode); + + /* Process input `msgs`. */ + + current = msgs; + + while (num_msgs > 0) { + if (num_msgs > 1) { + next = current + 1; + } else { + next = NULL; + } + + if (current->flags & I2C_MSG_READ) { + fsp_err = R_SCI_I2C_Read(&data->ctrl, current->buf, current->len, + next != NULL && (next->flags & I2C_MSG_RESTART)); + } else { + fsp_err = + R_SCI_I2C_Write(&data->ctrl, current->buf, current->len, + next != NULL && (next->flags & I2C_MSG_RESTART)); + } + + if (fsp_err != FSP_SUCCESS) { + switch (fsp_err) { + case FSP_ERR_INVALID_SIZE: + LOG_ERR("Provided number of bytes more than uint16_t size " + "(65535) while DTC is used for data transfer."); + break; + case FSP_ERR_IN_USE: + LOG_ERR("Bus busy condition. Another transfer was in progress."); + break; + default: + LOG_ERR("Unknown error."); + break; + } + + ret = -EIO; + goto RELEASE_BUS; + } + + /* Wait for callback to return. */ + k_sem_take(&data->complete_sem, K_FOREVER); + + /* Handle event msg from callback. */ + switch (data->event) { + case I2C_MASTER_EVENT_ABORTED: + LOG_ERR("%s failed.", (current->flags & I2C_MSG_READ) ? "Read" : "Write"); + ret = -EIO; + goto RELEASE_BUS; + case I2C_MASTER_EVENT_RX_COMPLETE: + break; + case I2C_MASTER_EVENT_TX_COMPLETE: + break; + default: + break; + } + + current++; + num_msgs--; + } + +RELEASE_BUS: + k_sem_give(&data->bus_lock); + + return ret; +} + +#ifdef CONFIG_I2C_CALLBACK + +static void renesas_ra_sci_i2c_async_done(const struct device *dev, struct sci_i2c_data *data, + int result) +{ + + i2c_callback_t cb = data->cb; + void *p_context = data->p_context; + + data->msg_idx = 0; + data->msgs = NULL; + data->num_msgs = 0; + data->cb = NULL; + data->p_context = NULL; + data->addr = 0; + + k_sem_give(&data->bus_lock); + + /* Callback may wish to start another transfer */ + cb(dev, result, p_context); +} + +/* Start a transfer asynchronously */ +static void renesas_ra_sci_i2c_async_iter(const struct device *dev) +{ + struct sci_i2c_data *data = dev->data; + fsp_err_t fsp_err; + struct i2c_msg *current, *next; + + struct i2c_msg *msg = &data->msgs[data->msg_idx]; + + /* Check for validity of all messages before transfer */ + current = msg; + if (data->msg_idx < (data->num_msgs - 1)) { + next = current + 1; + + /* + * Restart condition between messages + * of different directions is required + */ + if (OPERATION(current) != OPERATION(next)) { + if (!(next->flags & I2C_MSG_RESTART)) { + LOG_ERR("Restart condition between messages of " + "different directions is required." + "Current/Total: [%d/%d]", + data->msg_idx + 1, data->num_msgs); + renesas_ra_sci_i2c_async_done(dev, data, -EIO); + return; + } + } + + if (current->flags & I2C_MSG_STOP) { + LOG_ERR("Invalid stop flag. Stop condition is only allowed on " + "last message. " + "Current/Total: [%d/%d]", + data->msg_idx + 1, data->num_msgs); + renesas_ra_sci_i2c_async_done(dev, data, -EIO); + return; + } + } else { + current->flags |= I2C_MSG_STOP; + next = NULL; + } + + if (current->flags & I2C_MSG_READ) { + fsp_err = R_SCI_I2C_Read(&data->ctrl, current->buf, current->len, + (next != NULL) && (next->flags & I2C_MSG_RESTART)); + } else { + fsp_err = R_SCI_I2C_Write(&data->ctrl, current->buf, current->len, + (next != NULL) && (next->flags & I2C_MSG_RESTART)); + } + + /* Return an error if the transfer didn't start successfully + * e.g., if the bus was busy + */ + if (fsp_err != FSP_SUCCESS) { + switch (fsp_err) { + case FSP_ERR_INVALID_SIZE: + LOG_ERR("Provided number of bytes more than uint16_t size " + "(65535) while DTC is used for data transfer."); + break; + case FSP_ERR_IN_USE: + LOG_ERR("Bus busy condition. Another transfer was in progress."); + break; + default: + LOG_ERR("Unknown error."); + break; + } + + R_SCI_I2C_Abort(&data->ctrl); + return; + } +} + +static int renesas_ra_sci_i2c_transfer_cb(const struct device *dev, struct i2c_msg *msgs, + uint8_t num_msgs, uint16_t addr, i2c_callback_t cb, + void *p_context) +{ + struct sci_i2c_data *data = dev->data; + + int res = k_sem_take(&data->bus_lock, K_NO_WAIT); + + if (res != 0) { + return -EWOULDBLOCK; + } + + data->msg_idx = 0; + data->msgs = msgs; + data->num_msgs = num_msgs; + data->addr = addr; + data->cb = cb; + data->p_context = p_context; + + renesas_ra_sci_i2c_async_iter(dev); + + return 0; +} + +#endif /* CONFIG_I2C_CALLBACK */ + +static void renesas_ra_sci_i2c_callback(i2c_master_callback_args_t *p_args) +{ + const struct device *dev = p_args->p_context; + struct sci_i2c_data *data = dev->data; + +#ifdef CONFIG_I2C_CALLBACK + if (data->cb != NULL) { + /* Async transfer */ + if (p_args->event == I2C_MASTER_EVENT_ABORTED) { + R_SCI_I2C_Abort(&data->ctrl); + renesas_ra_sci_i2c_async_done(dev, data, -EIO); + } else if (data->msg_idx == data->num_msgs - 1) { + renesas_ra_sci_i2c_async_done(dev, data, 0); + } else { + data->msg_idx++; + renesas_ra_sci_i2c_async_iter(dev); + } + return; + } +#endif /* CONFIG_I2C_CALLBACK */ + + data->event = p_args->event; + + k_sem_give(&data->complete_sem); +} + +static int renesas_ra_sci_i2c_init(const struct device *dev) +{ + const struct sci_i2c_config *config = dev->config; + struct sci_i2c_data *data = (struct sci_i2c_data *)dev->data; + fsp_err_t fsp_err; + int ret; + + data->dev_config |= I2C_MODE_CONTROLLER; + + /* Configure dt provided device signals when available */ + ret = pinctrl_apply_state(config->pcfg, PINCTRL_STATE_DEFAULT); + + if (ret < 0) { + LOG_ERR("Pinctrl config failed."); + return ret; + } + + k_sem_init(&data->bus_lock, 1, 1); + k_sem_init(&data->complete_sem, 0, 1); + + switch (data->i2c_config.rate) { + case I2C_MASTER_RATE_STANDARD: + calc_sci_iic_clock_setting(dev, data->i2c_config.rate, + &data->ext_cfg.clock_settings); + data->i2c_config.p_extend = &data->ext_cfg; + data->dev_config |= I2C_SPEED_SET(I2C_SPEED_STANDARD); + break; + case I2C_MASTER_RATE_FAST: + calc_sci_iic_clock_setting(dev, data->i2c_config.rate, + &data->ext_cfg.clock_settings); + data->i2c_config.p_extend = &data->ext_cfg; + data->dev_config |= I2C_SPEED_SET(I2C_SPEED_FAST); + break; + default: + LOG_ERR("Invalid I2C speed rate: %d", data->i2c_config.rate); + return -ENOTSUP; + } + +#ifdef CONFIG_I2C_RENESAS_RA_SCI_DTC + data->i2c_config.p_transfer_rx = &data->rx_transfer; + data->i2c_config.p_transfer_tx = &data->tx_transfer; +#endif + + fsp_err = R_SCI_I2C_Open(&data->ctrl, &data->i2c_config); + + if (fsp_err != FSP_SUCCESS) { + LOG_ERR("I2C init failed."); + } + + config->irq_config_func(dev); + + return 0; +} + +static void calc_sci_iic_clock_setting(const struct device *dev, const uint32_t fsp_i2c_rate, + sci_i2c_clock_settings_t *clk_cfg) +{ + const struct sci_i2c_config *config = dev->config; + + uint32_t bitrate = 0; + bool use_mddr = clk_cfg->bitrate_modulation; + + uint32_t divisor = 0; + uint32_t divisor_bitrate_multiple = 0; + uint32_t brr = 0; + int32_t cks = 0; + uint32_t delta_error = 0; + + uint32_t sda_delay_clock = 0; + uint32_t sda_delay_counts = 0; + uint32_t temp_mddr; + uint32_t calculated_bitrate = 0; + + uint32_t mddr = MDDR_DISABLE; + + uint32_t peripheral_clock = R_FSP_SystemClockHzGet(BSP_FEATURE_SCI_CLOCK); + + uint32_t sda_delay_ns = config->sda_output_delay; + + if (I2C_MASTER_RATE_FAST == fsp_i2c_rate) { + bitrate = 400000; + } else { + bitrate = 100000; + } + + for (uint32_t i = 0; i <= 3; i++) { + + divisor_bitrate_multiple = (1 << (2 * (i + 1))) * 8; + divisor = divisor_bitrate_multiple * bitrate; + + /* Calculate BRR so that the bit rate is the largest possible value less than or + * equal to the desired bitrate. + */ + brr = (uint32_t)ceil(((double)peripheral_clock) / divisor - 1); + if (brr <= 255) { + break; + } + cks++; + } + calculated_bitrate = (uint32_t)((double)peripheral_clock) / + (divisor_bitrate_multiple * (256 / mddr) * (brr + 1)); + delta_error = bitrate - calculated_bitrate; + + if (use_mddr) { + for (uint32_t temp_brr = brr; temp_brr > 0; temp_brr--) { + + /** Calculate the MDDR (M) value if bit rate modulation is enabled, + * The formula to calculate MBBR (from the M and N relationship given in the + * hardware manual) is as follows and it must be between 128 and 256. MDDR = + * ((divisor * 256) * (BRR + 1)) / PCLK + */ + temp_mddr = (uint32_t)floor(((double)divisor) * 256 * (temp_brr + 1) / + peripheral_clock); + + /* The maximum value that could result from the calculation above is 256, + * which is a valid MDDR value, so only the lower bound is checked. + */ + if (temp_mddr < 128) { + break; + } + + /* The maximum for MDDR is 256 (MDDR unused). */ + if (temp_mddr > 256) { + continue; + } + + calculated_bitrate = + (uint32_t)(peripheral_clock / + (divisor_bitrate_multiple * (256 / ((double)temp_mddr)) * + (temp_brr + 1))); + + /** If the bit rate error is less than the previous lowest bit rate error, + * then store these settings as the best value. + */ + if ((bitrate - calculated_bitrate) < delta_error) { + delta_error = bitrate - calculated_bitrate; + brr = temp_brr; + mddr = temp_mddr; + } + } + } + + /* If MDDR == 256, disable bitrate modulation and set MDDR to a valid value. */ + if (mddr == 256) { + mddr = 255; + use_mddr = false; + } + + /* Calculate SDA delay. */ + sda_delay_clock = peripheral_clock >> cks; + sda_delay_counts = (uint32_t)ceil(((double)sda_delay_ns) * sda_delay_clock / 1000000000); + if (sda_delay_counts > 31) { + sda_delay_counts = 31; + } + + clk_cfg->clk_divisor_value = (uint8_t)cks; + clk_cfg->brr_value = (uint8_t)brr; + clk_cfg->mddr_value = (uint8_t)mddr; + clk_cfg->bitrate_modulation = use_mddr; + clk_cfg->cycles_value = (uint8_t)sda_delay_counts; +} + +static const struct i2c_driver_api renesas_ra_sci_i2c_driver_api = { + .configure = renesas_ra_sci_i2c_configure, + .get_config = renesas_ra_sci_i2c_get_config, + .transfer = renesas_ra_sci_i2c_transfer, +#ifdef CONFIG_I2C_CALLBACK + .transfer_cb = renesas_ra_sci_i2c_transfer_cb, +#endif /* CONFIG_I2C_CALLBACK */ +}; + +#define _ELC_EVENT_SCI_RXI(channel) ELC_EVENT_SCI##channel##_RXI +#define _ELC_EVENT_SCI_TXI(channel) ELC_EVENT_SCI##channel##_TXI +#define _ELC_EVENT_SCI_TEI(channel) ELC_EVENT_SCI##channel##_TEI + +#define ELC_EVENT_SCI_RXI(channel) _ELC_EVENT_SCI_RXI(channel) +#define ELC_EVENT_SCI_TXI(channel) _ELC_EVENT_SCI_TXI(channel) +#define ELC_EVENT_SCI_TEI(channel) _ELC_EVENT_SCI_TEI(channel) + +#ifndef CONFIG_I2C_RENESAS_RA_SCI_DTC +#define SCI_I2C_DTC_INIT(index) +#define RXI_TRANSFER(index) +#else +#define SCI_I2C_DTC_INIT(index) \ + .rx_transfer_info = \ + { \ + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \ + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_DESTINATION, \ + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, \ + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \ + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_FIXED, \ + .transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \ + .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \ + .p_dest = (void *)NULL, \ + .p_src = (void const *)NULL, \ + .num_blocks = 0, \ + .length = 0, \ + }, \ + .rx_transfer_cfg_extend = {.activation_source = \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)}, \ + .rx_transfer_cfg = \ + { \ + .p_info = &sci_i2c_data_##index.rx_transfer_info, \ + .p_extend = &sci_i2c_data_##index.rx_transfer_cfg_extend, \ + }, \ + .rx_transfer = \ + { \ + .p_ctrl = &sci_i2c_data_##index.rx_transfer_ctrl, \ + .p_cfg = &sci_i2c_data_##index.rx_transfer_cfg, \ + .p_api = &g_transfer_on_dtc, \ + }, \ + .tx_transfer_info = \ + { \ + .transfer_settings_word_b.dest_addr_mode = TRANSFER_ADDR_MODE_FIXED, \ + .transfer_settings_word_b.repeat_area = TRANSFER_REPEAT_AREA_SOURCE, \ + .transfer_settings_word_b.irq = TRANSFER_IRQ_END, \ + .transfer_settings_word_b.chain_mode = TRANSFER_CHAIN_MODE_DISABLED, \ + .transfer_settings_word_b.src_addr_mode = TRANSFER_ADDR_MODE_INCREMENTED, \ + .transfer_settings_word_b.size = TRANSFER_SIZE_1_BYTE, \ + .transfer_settings_word_b.mode = TRANSFER_MODE_NORMAL, \ + .p_dest = (void *)NULL, \ + .p_src = (void const *)NULL, \ + .num_blocks = 0, \ + .length = 0, \ + }, \ + .tx_transfer_cfg_extend = {.activation_source = \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)}, \ + .tx_transfer_cfg = \ + { \ + .p_info = &sci_i2c_data_##index.tx_transfer_info, \ + .p_extend = &sci_i2c_data_##index.tx_transfer_cfg_extend, \ + }, \ + .tx_transfer = { \ + .p_ctrl = &sci_i2c_data_##index.tx_transfer_ctrl, \ + .p_cfg = &sci_i2c_data_##index.tx_transfer_cfg, \ + .p_api = &g_transfer_on_dtc, \ + }, + +#define RXI_TRANSFER(index) \ + /* rxi */ \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)] = \ + ELC_EVENT_SCI_RXI(DT_INST_PROP(index, channel)); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, priority), sci_i2c_rxi_isr, \ + DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq)); +#endif + +#define SCI_I2C_RA_INIT(index) \ + static void renesas_ra_sci_i2c_irq_config_func##index(const struct device *dev) \ + { \ + RXI_TRANSFER(index) \ + \ + /* txi */ \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)] = \ + ELC_EVENT_SCI_TXI(DT_INST_PROP(index, channel)); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, priority), \ + sci_i2c_txi_isr, DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq)); \ + \ + /* tei */ \ + R_ICU->IELSR[DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)] = \ + ELC_EVENT_SCI_TEI(DT_INST_PROP(index, channel)); \ + IRQ_CONNECT(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \ + DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, priority), \ + sci_i2c_tei_isr, DEVICE_DT_INST_GET(index), 0); \ + irq_enable(DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq)); \ + } \ + PINCTRL_DT_DEFINE(DT_INST_PARENT(index)); \ + \ + static const struct sci_i2c_config sci_i2c_config_##index = { \ + .pcfg = PINCTRL_DT_DEV_CONFIG_GET(DT_INST_PARENT(index)), \ + .irq_config_func = renesas_ra_sci_i2c_irq_config_func##index, \ + .sda_output_delay = DT_INST_PROP(index, sda_output_delay), \ + }; \ + static struct sci_i2c_data sci_i2c_data_##index = { \ + .i2c_config = \ + { \ + .channel = DT_INST_PROP(index, channel), \ + .slave = 0, \ + .rate = I2C_MASTER_RATE_STANDARD, \ + .addr_mode = I2C_MASTER_ADDR_MODE_7BIT, \ + .ipl = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, priority), \ + .rxi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), rxi, irq), \ + .txi_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), txi, irq), \ + .tei_irq = DT_IRQ_BY_NAME(DT_INST_PARENT(index), tei, irq), \ + .p_callback = renesas_ra_sci_i2c_callback, \ + .p_context = (void *)DEVICE_DT_GET(DT_DRV_INST(index)), \ + }, \ + .ext_cfg = \ + { \ + .clock_settings.snfr_value = \ + DT_INST_PROP(index, noise_filter_clock_select), \ + .clock_settings.bitrate_modulation = DT_INST_NODE_HAS_PROP( \ + index, bit_rate_modulation), \ + }, \ + SCI_I2C_DTC_INIT(index)}; \ + I2C_DEVICE_DT_INST_DEFINE(index, renesas_ra_sci_i2c_init, NULL, &sci_i2c_data_##index, \ + &sci_i2c_config_##index, POST_KERNEL, \ + CONFIG_I2C_INIT_PRIORITY, &renesas_ra_sci_i2c_driver_api); + +DT_INST_FOREACH_STATUS_OKAY(SCI_I2C_RA_INIT) diff --git a/dts/bindings/i2c/renesas,ra-i2c-sci.yaml b/dts/bindings/i2c/renesas,ra-i2c-sci.yaml new file mode 100644 index 0000000000000..16801d5697437 --- /dev/null +++ b/dts/bindings/i2c/renesas,ra-i2c-sci.yaml @@ -0,0 +1,34 @@ +# Copyright (c) 2025 Renesas Electronics Corporation +# SPDX-License-Identifier: Apache-2.0 + +description: Renesas RA SCI I2C controller + +compatible: "renesas,ra-i2c-sci" + +include: [i2c-controller.yaml, pinctrl-device.yaml] + +properties: + + channel: + required: true + type: int + + sda-output-delay: + type: int + default: 300 + description: | + SDA Output Delay in nano seconds. + + noise-filter-clock-select: + type: int + default: 1 + enum: [1, 2, 3, 4] + description: | + Select the on-chip baud rate generator source clock + division setting for the digital noise filter. + + bit-rate-modulation: + type: boolean + description: | + Enabling bitrate modulation reduces the percent error + of the actual bitrate with respect to the requested baud rate. diff --git a/modules/Kconfig.renesas b/modules/Kconfig.renesas index 2ce3656a0e0c2..257f780aaf3fd 100644 --- a/modules/Kconfig.renesas +++ b/modules/Kconfig.renesas @@ -45,6 +45,11 @@ config USE_RA_FSP_I2C_IIC help Enable Renesas RA I2C IIC Master driver +config USE_RA_FSP_SCI_I2C + bool + help + Enable RA FSP SCI I2C driver + config USE_RA_FSP_SCI_B_I2C bool help From 3c8457f43ba8242d6e7897c0d80d8423a26fd115 Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Mon, 29 Sep 2025 11:38:51 +0700 Subject: [PATCH 2/6] dts: arm: add SCI I2C device node for RA6 series Add I2C device nodes for the SCI peripheral on RA6 series Signed-off-by: Khai Cao --- dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi | 32 +++++++++++ dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi | 24 ++++++++ dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi | 24 ++++++++ dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi | 64 +++++++++++++++++++++ dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi | 64 +++++++++++++++++++++ dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi | 16 ++++++ dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi | 56 ++++++++++++++++++ 7 files changed, 280 insertions(+) diff --git a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi index b897007aa0434..e918669da2846 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6e10x.dtsi @@ -52,6 +52,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -67,6 +75,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -82,6 +98,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -97,6 +121,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi index 0a613494c90cb..2cc6b19ccf6ec 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m2ax.dtsi @@ -31,6 +31,14 @@ channel = <5>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + status = "disabled"; + }; }; sci6: sci6@400700c0 { @@ -44,6 +52,14 @@ channel = <6>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + status = "disabled"; + }; }; sci7: sci7@400700e0 { @@ -59,6 +75,14 @@ channel = <7>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + status = "disabled"; + }; }; iic2: iic2@40053200 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi index 7c6e85dd27349..30df0b53af9f4 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m3ax.dtsi @@ -69,6 +69,14 @@ channel = <5>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + status = "disabled"; + }; }; sci6: sci6@400700c0 { @@ -84,6 +92,14 @@ channel = <6>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + status = "disabled"; + }; }; sci7: sci7@400700e0 { @@ -99,6 +115,14 @@ channel = <7>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + status = "disabled"; + }; }; iic2: iic2@40053200 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi index 3296e4159cb15..b199147003f77 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m4ax.dtsi @@ -29,6 +29,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -44,6 +52,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -59,6 +75,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -74,6 +98,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; sci5: sci5@40118500 { @@ -89,6 +121,14 @@ channel = <5>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + status = "disabled"; + }; }; sci6: sci6@40118600 { @@ -104,6 +144,14 @@ channel = <6>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + status = "disabled"; + }; }; sci7: sci7@40118700 { @@ -119,6 +167,14 @@ channel = <7>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + status = "disabled"; + }; }; sci8: sci8@40118800 { @@ -134,6 +190,14 @@ channel = <8>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi index 1985def1d3ac3..899f4b3d0dacc 100644 --- a/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi +++ b/dts/arm/renesas/ra/ra6/r7fa6m5xh.dtsi @@ -89,6 +89,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -104,6 +112,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -119,6 +135,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -134,6 +158,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; sci5: sci5@40118500 { @@ -149,6 +181,14 @@ channel = <5>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + status = "disabled"; + }; }; sci6: sci6@40118600 { @@ -164,6 +204,14 @@ channel = <6>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <6>; + status = "disabled"; + }; }; sci7: sci7@40118700 { @@ -179,6 +227,14 @@ channel = <7>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <7>; + status = "disabled"; + }; }; sci8: sci8@40118800 { @@ -194,6 +250,14 @@ channel = <8>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + status = "disabled"; + }; }; iic2: iic2@4009f200 { diff --git a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi index 2d2a08198ab83..5fdf797779dc1 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm33-common.dtsi @@ -137,6 +137,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-sci-i2c"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci9: sci9@40118900 { @@ -152,6 +160,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-sci-i2c"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; iic0: iic0@4009f000 { diff --git a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi index c6d82b8b3c406..af760df763de8 100644 --- a/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra6/ra6-cm4-common.dtsi @@ -155,6 +155,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -168,6 +176,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci2@40070040 { @@ -181,6 +197,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci3@40070060 { @@ -194,6 +218,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40070080 { @@ -207,6 +239,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; sci8: sci8@40070100 { @@ -222,6 +262,14 @@ channel = <8>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <8>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -237,6 +285,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; iic0: iic0@40053000 { From 71e80893b2f7119f35aa2a7916a586ee2d004e52 Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Mon, 29 Sep 2025 11:39:25 +0700 Subject: [PATCH 3/6] dts: arm: add SCI I2C device node for RA4 series Add I2C device nodes for the SCI peripheral on RA4 series Signed-off-by: Khai Cao --- dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi | 48 +++++++++++++++++++++ dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi | 16 +++++++ dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi | 48 +++++++++++++++++++++ dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi | 8 ++++ dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi | 32 ++++++++++++++ dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi | 32 ++++++++++++++ dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi | 8 ++++ dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi | 16 +++++++ dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi | 24 +++++++++++ 9 files changed, 232 insertions(+) diff --git a/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi b/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi index 66b563207c42b..23c37fa535a99 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4c1bx.dtsi @@ -160,6 +160,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci1: sci1@40118100 { @@ -173,6 +181,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -186,6 +202,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -199,6 +223,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; sci5: sci@40118500 { @@ -212,6 +244,14 @@ channel = <5>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + status = "disabled"; + }; }; sci9: sci@40118900 { @@ -225,6 +265,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; spi0: spi@4011a000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi index fe641e8303cba..b184c7fbf88b8 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4e10x.dtsi @@ -35,6 +35,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -48,6 +56,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi index be1c7973d6156..99e68eec49ba3 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4l1bx.dtsi @@ -170,6 +170,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci1: sci@40118100 { @@ -183,6 +191,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci3: sci@40118300 { @@ -196,6 +212,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci@40118400 { @@ -209,6 +233,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; sci5: sci@40118500 { @@ -224,6 +256,14 @@ channel = <5>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <5>; + status = "disabled"; + }; }; sci9: sci@40118900 { @@ -239,6 +279,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; spi0: spi@4011a000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi index 7f3e9e5af8f24..628fc8c442b66 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m1ax.dtsi @@ -58,6 +58,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; adc@4005c000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi index a9d19714050e3..e0c4e598dad88 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m2ax.dtsi @@ -53,6 +53,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -68,6 +76,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -83,6 +99,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -98,6 +122,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi index 4eb9a85553c73..9bf6ed7324ad3 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4m3ax.dtsi @@ -62,6 +62,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci2@40118200 { @@ -77,6 +85,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci3@40118300 { @@ -92,6 +108,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci4: sci4@40118400 { @@ -107,6 +131,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; adc@40170000 { diff --git a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi index 2ced5b3fb24a3..2097cec1638a6 100644 --- a/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi +++ b/dts/arm/renesas/ra/ra4/r7fa4w1ad2cng.dtsi @@ -36,6 +36,14 @@ channel = <4>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <4>; + status = "disabled"; + }; }; trng: trng { diff --git a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi index 28cb01aeb1bb7..d3bdde34f3be4 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm33-common.dtsi @@ -145,6 +145,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci9: sci9@40118900 { @@ -160,6 +168,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; spi0: spi@4011a000 { diff --git a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi index 27b9ec78a301c..44cb32f2676c9 100644 --- a/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi +++ b/dts/arm/renesas/ra/ra4/ra4-cm4-common.dtsi @@ -150,6 +150,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -165,6 +173,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -178,6 +194,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; spi0: spi@40072000 { From fea429d8292a9449f9829c3b36132fc64ffdf8ae Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Mon, 29 Sep 2025 11:39:53 +0700 Subject: [PATCH 4/6] dts: arm: add SCI I2C device node for RA2 series Add I2C device nodes for the SCI peripheral on RA2 series Signed-off-by: Khai Cao --- dts/arm/renesas/ra/ra2/ra2l1.dtsi | 40 +++++++++++++++++++++++++++++++ dts/arm/renesas/ra/ra2/ra2xx.dtsi | 40 +++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/dts/arm/renesas/ra/ra2/ra2l1.dtsi b/dts/arm/renesas/ra/ra2/ra2l1.dtsi index fe6ff9896072b..e79437c5db754 100644 --- a/dts/arm/renesas/ra/ra2/ra2l1.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2l1.dtsi @@ -191,6 +191,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci1: sci1@40070020 { @@ -204,6 +212,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci2@40070040 { @@ -217,6 +233,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci3@40070060 { @@ -230,6 +254,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci9: sci9@40070120 { @@ -245,6 +277,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; wdt: wdt@40044200 { diff --git a/dts/arm/renesas/ra/ra2/ra2xx.dtsi b/dts/arm/renesas/ra/ra2/ra2xx.dtsi index 8f32511c9cec9..7c16b1f684c07 100644 --- a/dts/arm/renesas/ra/ra2/ra2xx.dtsi +++ b/dts/arm/renesas/ra/ra2/ra2xx.dtsi @@ -158,6 +158,14 @@ channel = <0>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <0>; + status = "disabled"; + }; }; sci1: sci@40070020 { @@ -173,6 +181,14 @@ channel = <1>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <1>; + status = "disabled"; + }; }; sci2: sci@40070040 { @@ -188,6 +204,14 @@ channel = <2>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <2>; + status = "disabled"; + }; }; sci3: sci@40070060 { @@ -203,6 +227,14 @@ channel = <3>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <3>; + status = "disabled"; + }; }; sci9: sci@40070120 { @@ -218,6 +250,14 @@ channel = <9>; status = "disabled"; }; + + i2c { + compatible = "renesas,ra-i2c-sci"; + #address-cells = <1>; + #size-cells = <0>; + channel = <9>; + status = "disabled"; + }; }; spi0: spi@40072000 { From f2dc11483be3ab186d87270b00ff169831cbe0ab Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Mon, 29 Sep 2025 11:40:14 +0700 Subject: [PATCH 5/6] boards: renesas: Add SCI I2C node on Renesas RA boards Enable support of i2c sci driver on these boards: ek_ra6m5, ek_ra6m4 Signed-off-by: Khai Cao --- boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi | 10 ++++++++++ boards/renesas/ek_ra6m4/ek_ra6m4.dts | 11 +++++++++++ boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi | 10 ++++++++++ boards/renesas/ek_ra6m5/ek_ra6m5.dts | 11 +++++++++++ 4 files changed, 42 insertions(+) diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi index 3eca01a46c8e0..599661c620e15 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m4/ek_ra6m4-pinctrl.dtsi @@ -12,6 +12,16 @@ }; }; + sci2_default: sci2_default { + group1 { + /* sda scl */ + psels = , + ; + drive-strength = "medium"; + drive-open-drain; + }; + }; + sci7_default: sci7_default { group1 { /* tx rx */ diff --git a/boards/renesas/ek_ra6m4/ek_ra6m4.dts b/boards/renesas/ek_ra6m4/ek_ra6m4.dts index c46e6a1cdee62..3331775af4ee4 100644 --- a/boards/renesas/ek_ra6m4/ek_ra6m4.dts +++ b/boards/renesas/ek_ra6m4/ek_ra6m4.dts @@ -133,6 +133,17 @@ }; }; +&sci2 { + pinctrl-0 = <&sci2_default>; + pinctrl-names = "default"; + + i2c2: i2c { + sda-output-delay = <300>; + noise-filter-clock-select = <1>; + bit-rate-modulation; + }; +}; + &sci7 { pinctrl-0 = <&sci7_default>; pinctrl-names = "default"; diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi index c626e7832247b..0a9f7c94453c3 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi +++ b/boards/renesas/ek_ra6m5/ek_ra6m5-pinctrl.dtsi @@ -12,6 +12,16 @@ }; }; + sci2_default: sci2_default { + group1 { + /* sda scl */ + psels = , + ; + drive-strength = "medium"; + drive-open-drain; + }; + }; + sci7_default: sci7_default { group1 { /* tx rx */ diff --git a/boards/renesas/ek_ra6m5/ek_ra6m5.dts b/boards/renesas/ek_ra6m5/ek_ra6m5.dts index 5d43d0d83a970..6e06fdf80e239 100644 --- a/boards/renesas/ek_ra6m5/ek_ra6m5.dts +++ b/boards/renesas/ek_ra6m5/ek_ra6m5.dts @@ -133,6 +133,17 @@ }; }; +&sci2 { + pinctrl-0 = <&sci2_default>; + pinctrl-names = "default"; + + i2c2: i2c { + sda-output-delay = <300>; + noise-filter-clock-select = <1>; + bit-rate-modulation; + }; +}; + &sci7 { pinctrl-0 = <&sci7_default>; pinctrl-names = "default"; From b7378619b09369dc5c7e14e70aeacb41dd97a33d Mon Sep 17 00:00:00 2001 From: Khai Cao Date: Mon, 29 Sep 2025 11:40:33 +0700 Subject: [PATCH 6/6] tests: i2c: add support for i2c sci on Renesas RA boards Add board support for EK_RA6M5, EK_RA6M4 i2c test use sci_i2c: - tests/drivers/i2c/i2c_api Example for i2c use sci_i2c: west build -b ek_ra6m5 tests/drivers/i2c/i2c_api/ -p always \ -DDTC_OVERLAY_FILE=boards/ek_ra6m5_sci_i2c.overlay \ -DCONF_FILE="boards/ek_ra6m5_sci_i2c.conf" Signed-off-by: Khai Cao --- .../i2c/i2c_api/boards/ek_ra6m4_sci_i2c.conf | 3 +++ .../i2c_api/boards/ek_ra6m4_sci_i2c.overlay | 19 +++++++++++++++++++ .../i2c/i2c_api/boards/ek_ra6m5_sci_i2c.conf | 3 +++ .../i2c_api/boards/ek_ra6m5_sci_i2c.overlay | 19 +++++++++++++++++++ tests/drivers/i2c/i2c_api/testcase.yaml | 12 ++++++++++++ 5 files changed, 56 insertions(+) create mode 100644 tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.conf create mode 100644 tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.overlay create mode 100644 tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.conf create mode 100644 tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.overlay diff --git a/tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.conf b/tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.conf new file mode 100644 index 0000000000000..fc3333d47c76e --- /dev/null +++ b/tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.conf @@ -0,0 +1,3 @@ +CONFIG_I2C=y +CONFIG_ZTEST=y +CONFIG_SENSOR_GY271_QMC=y diff --git a/tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.overlay b/tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.overlay new file mode 100644 index 0000000000000..77114d1224b71 --- /dev/null +++ b/tests/drivers/i2c/i2c_api/boards/ek_ra6m4_sci_i2c.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + i2c-0 = &i2c2; + gy271 = &i2c2; + }; +}; + +&sci2 { + status = "okay"; + + i2c2: i2c { + status = "okay"; + }; +}; diff --git a/tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.conf b/tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.conf new file mode 100644 index 0000000000000..fc3333d47c76e --- /dev/null +++ b/tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.conf @@ -0,0 +1,3 @@ +CONFIG_I2C=y +CONFIG_ZTEST=y +CONFIG_SENSOR_GY271_QMC=y diff --git a/tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.overlay b/tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.overlay new file mode 100644 index 0000000000000..77114d1224b71 --- /dev/null +++ b/tests/drivers/i2c/i2c_api/boards/ek_ra6m5_sci_i2c.overlay @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Renesas Electronics Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + aliases { + i2c-0 = &i2c2; + gy271 = &i2c2; + }; +}; + +&sci2 { + status = "okay"; + + i2c2: i2c { + status = "okay"; + }; +}; diff --git a/tests/drivers/i2c/i2c_api/testcase.yaml b/tests/drivers/i2c/i2c_api/testcase.yaml index 1f31eeea5e53f..0ee8dfc8d27c2 100644 --- a/tests/drivers/i2c/i2c_api/testcase.yaml +++ b/tests/drivers/i2c/i2c_api/testcase.yaml @@ -31,6 +31,18 @@ tests: extra_args: - DTC_OVERLAY_FILE="./boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}_sci_b_i2c.overlay" - CONF_FILE="./prj.conf ./boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}_sci_b_i2c.conf" + drivers.i2c.renesas_sci_i2c.api: + depends_on: i2c + tags: + - drivers + - i2c + filter: dt_alias_exists("gy271") and CONFIG_I2C_RENESAS_RA_SCI + platform_allow: + - ek_ra6m5 + - ek_ra6m4 + extra_args: + - DTC_OVERLAY_FILE="./boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}_sci_i2c.overlay" + - CONF_FILE="./prj.conf ./boards/${BOARD}${NORMALIZED_BOARD_QUALIFIERS}_sci_i2c.conf" drivers.i2c.stm32.interrupt_disabled: depends_on: - i2c