/* * Copyright (c) 2019-2021 Vestas Wind Systems A/S * * Based on clock_control_mcux_sim.c, which is: * Copyright (c) 2017, NXP * * SPDX-License-Identifier: Apache-2.0 */ #define DT_DRV_COMPAT nxp_kinetis_scg #include #include #include #include #define LOG_LEVEL CONFIG_CLOCK_CONTROL_LOG_LEVEL #include LOG_MODULE_REGISTER(clock_control_scg); #define MCUX_SCG_CLOCK_NODE(name) DT_CHILD(DT_DRV_INST(0), name) static int mcux_scg_on(const struct device *dev, clock_control_subsys_t sub_system) { return 0; } static int mcux_scg_off(const struct device *dev, clock_control_subsys_t sub_system) { return 0; } static int mcux_scg_get_rate(const struct device *dev, clock_control_subsys_t sub_system, uint32_t *rate) { clock_name_t clock_name; switch ((uint32_t) sub_system) { case KINETIS_SCG_CORESYS_CLK: clock_name = kCLOCK_CoreSysClk; break; case KINETIS_SCG_BUS_CLK: clock_name = kCLOCK_BusClk; break; case KINETIS_SCG_FLEXBUS_CLK: clock_name = kCLOCK_FlexBusClk; break; case KINETIS_SCG_FLASH_CLK: clock_name = kCLOCK_FlashClk; break; case KINETIS_SCG_SOSC_CLK: clock_name = kCLOCK_ScgSysOscClk; break; case KINETIS_SCG_SIRC_CLK: clock_name = kCLOCK_ScgSircClk; break; case KINETIS_SCG_FIRC_CLK: clock_name = kCLOCK_ScgFircClk; break; case KINETIS_SCG_SPLL_CLK: clock_name = kCLOCK_ScgSysPllClk; break; case KINETIS_SCG_SOSC_ASYNC_DIV1_CLK: clock_name = kCLOCK_ScgSysOscAsyncDiv1Clk; break; case KINETIS_SCG_SOSC_ASYNC_DIV2_CLK: clock_name = kCLOCK_ScgSysOscAsyncDiv2Clk; break; case KINETIS_SCG_SIRC_ASYNC_DIV1_CLK: clock_name = kCLOCK_ScgSircAsyncDiv1Clk; break; case KINETIS_SCG_SIRC_ASYNC_DIV2_CLK: clock_name = kCLOCK_ScgSircAsyncDiv2Clk; break; case KINETIS_SCG_FIRC_ASYNC_DIV1_CLK: clock_name = kCLOCK_ScgFircAsyncDiv1Clk; break; case KINETIS_SCG_FIRC_ASYNC_DIV2_CLK: clock_name = kCLOCK_ScgFircAsyncDiv2Clk; break; case KINETIS_SCG_SPLL_ASYNC_DIV1_CLK: clock_name = kCLOCK_ScgSysPllAsyncDiv1Clk; break; case KINETIS_SCG_SPLL_ASYNC_DIV2_CLK: clock_name = kCLOCK_ScgSysPllAsyncDiv2Clk; break; default: LOG_ERR("Unsupported clock name"); return -EINVAL; } *rate = CLOCK_GetFreq(clock_name); return 0; } static int mcux_scg_init(const struct device *dev) { #if DT_NODE_HAS_STATUS(MCUX_SCG_CLOCK_NODE(clkout_clk), okay) #if DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(slow_clk)) CLOCK_SetClkOutSel(kClockClkoutSelScgSlow); #elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(sosc_clk)) CLOCK_SetClkOutSel(kClockClkoutSelSysOsc); #elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(sirc_clk)) CLOCK_SetClkOutSel(kClockClkoutSelSirc); #elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(firc_clk)) CLOCK_SetClkOutSel(kClockClkoutSelFirc); #elif DT_SAME_NODE(DT_CLOCKS_CTLR(MCUX_SCG_CLOCK_NODE(clkout_clk)), MCUX_SCG_CLOCK_NODE(spll_clk)) CLOCK_SetClkOutSel(kClockClkoutSelSysPll); #else #error Unsupported SCG clkout clock source #endif #endif /* DT_NODE_HAS_STATUS(MCUX_SCG_CLOCK_NODE(clkout_clk), okay) */ return 0; } static const struct clock_control_driver_api mcux_scg_driver_api = { .on = mcux_scg_on, .off = mcux_scg_off, .get_rate = mcux_scg_get_rate, }; DEVICE_DT_INST_DEFINE(0, &mcux_scg_init, NULL, NULL, NULL, PRE_KERNEL_1, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, &mcux_scg_driver_api);