Skip to content

Commit

Permalink
drivers: i3c: npcx: introduce I3C driver
Browse files Browse the repository at this point in the history
This implements basic driver to utilize the I3C IP block
on NPCX.

1. I3C mode: Main controller mode only.
2. Transfer: Support SDR only.
3. IBI: Support Hot-Join, IBI(MDB).
   Controller request is not supported.
4. Support 3 I3C modules:
   I3C1(3.3V), I3C2(1.8V, espi mode), (I3C3 1.8V or 3.3V)

Signed-off-by: Alvis Sun <yfsun@nuvoton.com>
  • Loading branch information
alvsun committed Apr 11, 2024
1 parent b9f3d68 commit 76929bc
Show file tree
Hide file tree
Showing 14 changed files with 2,524 additions and 6 deletions.
15 changes: 15 additions & 0 deletions boards/nuvoton/npcx4m8f_evb/npcx4m8f_evb.dts
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,18 @@
compatible = "zephyr,kscan-input";
};
};

&i3c0 {
pinctrl-0 = <&i3c1_sda_scl_gpe3_e4>;
pinctrl-names = "default";
};

&i3c1 {
pinctrl-0 = <&i3c2_sda_scl_gp50_56>;
pinctrl-names = "default";
};

&i3c2 {
pinctrl-0 = <&i3c3_sda_scl_gpf4_f5>;
pinctrl-names = "default";
};
11 changes: 11 additions & 0 deletions drivers/clock_control/clock_control_npcx.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ static int npcx_clock_control_get_subsys_rate(const struct device *dev,
case NPCX_CLOCK_BUS_FMCLK:
*rate = FMCLK;
break;
case NPCX_CLOCK_BUS_MCLKD:
*rate = OFMCLK/(MCLKD_SL + 1);
break;
default:
*rate = 0U;
/* Invalid parameters */
Expand Down Expand Up @@ -185,6 +188,13 @@ BUILD_ASSERT(APBSRC_CLK / (APB4DIV_VAL + 1) <= MAX_OFMCLK &&
(APB4DIV_VAL + 1) % (FPRED_VAL + 1) == 0,
"Invalid APB4_CLK setting");
#endif
#if defined(CONFIG_I3C)
BUILD_ASSERT(OFMCLK / (MCLKD_SL + 1) <= MHZ(50) &&
OFMCLK / (MCLKD_SL + 1) >= MHZ(40),
"Invalid MCLKD_SL setting");
BUILD_ASSERT(APBSRC_CLK / (APB4DIV_VAL + 1) >= MHZ(20),
"Invalid PDMA CLK setting");
#endif

static int npcx_clock_control_init(const struct device *dev)
{
Expand Down Expand Up @@ -222,6 +232,7 @@ static int npcx_clock_control_init(const struct device *dev)
inst_cdcg->HFCBCD = VAL_HFCBCD;
inst_cdcg->HFCBCD1 = VAL_HFCBCD1;
inst_cdcg->HFCBCD2 = VAL_HFCBCD2;
inst_cdcg->HFCBCD3 = VAL_HFCBCD3;

/*
* Power-down (turn off clock) the modules initially for better
Expand Down
5 changes: 5 additions & 0 deletions drivers/i3c/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ zephyr_library_sources_ifdef(
i3c_cdns.c
)

zephyr_library_sources_ifdef(
CONFIG_I3C_NPCX
i3c_npcx.c
)

zephyr_library_sources_ifdef(
CONFIG_I3C_TEST
i3c_test.c
Expand Down
1 change: 1 addition & 0 deletions drivers/i3c/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ comment "Device Drivers"

rsource "Kconfig.nxp"
rsource "Kconfig.cdns"
rsource "Kconfig.npcx"
rsource "Kconfig.test"

endif # I3C
33 changes: 33 additions & 0 deletions drivers/i3c/Kconfig.npcx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# NPCX I3C driver configuration options
# SPDX-License-Identifier: Apache-2.0

DT_I3C_NPCX := $(dt_nodelabel_path,i3c0)

config I3C_NPCX
bool "Nuvoton NPCX embedded controller (EC) I3C driver"
depends on DT_HAS_NUVOTON_NPCX_I3C_ENABLED
select RESET
select I3C_IBI_WORKQUEUE if I3C_USE_IBI
default y
help
This option enables the I3C driver for NPCX family of
processors.
Say y if you wish to use I3C channels on NPCX MCU.

# Expose this option when the 'reg' property includes the MDMA base address
# as the second group in the phandle-array.
# i.e. I3C node example in dtsi file.
# i3c0: i3c@400f0000 {
# ....
# /* reg[0]: I3C_1 register, reg[1]: MDMA5 register */
# reg-names = "i3c1", "mdma5";
# reg = <0x400f0000 0x2000>,
# <0x40011500 0x100>;
# ....
# }
config I3C_NPCX_DMA
bool "Nuvoton NPCX embedded controller (EC) serial driver DMA support"
depends on I3C_NPCX && "$(dt_node_reg_addr_hex,$(DT_I3C_NPCX),1)" != 0
default y
help
Enable support for npcx I3C DMA mode.
7 changes: 3 additions & 4 deletions drivers/i3c/i3c_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,7 +454,7 @@ int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
goto out;
}

if (desc->dynamic_addr != 0U) {
if (desc != NULL && desc->dynamic_addr != 0U) {
if (assigned_okay) {
/* Return the already assigned address if desired so. */
dyn_addr = desc->dynamic_addr;
Expand All @@ -477,9 +477,8 @@ int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
* Use the desired dynamic address as the new dynamic address
* if the slot is free.
*/
if (desc->init_dynamic_addr != 0U) {
if (i3c_addr_slots_is_free(addr_slots,
desc->init_dynamic_addr)) {
if (desc != NULL && desc->init_dynamic_addr != 0U) {
if (i3c_addr_slots_is_free(addr_slots, desc->init_dynamic_addr)) {
dyn_addr = desc->init_dynamic_addr;
goto out;
}
Expand Down

0 comments on commit 76929bc

Please sign in to comment.