drivers: clock_control: Add Ambiq clock_control driver.
This commit adds Ambiq clock_control driver support. Signed-off-by: Aaron Ye <aye@ambiq.com>
This commit is contained in:
@@ -27,6 +27,7 @@ zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_SMARTBOND clock_cont
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NUMAKER_SCC clock_control_numaker_scc.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_NXP_S32 clock_control_nxp_s32.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_RA clock_control_ra.c)
|
||||
zephyr_library_sources_ifdef(CONFIG_CLOCK_CONTROL_AMBIQ clock_control_ambiq.c)
|
||||
|
||||
|
||||
if(CONFIG_CLOCK_CONTROL_STM32_CUBE)
|
||||
|
||||
@@ -82,4 +82,6 @@ source "drivers/clock_control/Kconfig.agilex5"
|
||||
|
||||
source "drivers/clock_control/Kconfig.ra"
|
||||
|
||||
source "drivers/clock_control/Kconfig.ambiq"
|
||||
|
||||
endif # CLOCK_CONTROL
|
||||
|
||||
14
drivers/clock_control/Kconfig.ambiq
Normal file
14
drivers/clock_control/Kconfig.ambiq
Normal file
@@ -0,0 +1,14 @@
|
||||
# Ambiq Clock Control Driver configuration options
|
||||
#
|
||||
# Copyright (c) 2023 Ambiq Micro Inc.
|
||||
#
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
config CLOCK_CONTROL_AMBIQ
|
||||
bool "AMBIQ clock control driver"
|
||||
default y
|
||||
depends on DT_HAS_AMBIQ_CLKCTRL_ENABLED
|
||||
select AMBIQ_HAL
|
||||
help
|
||||
Enable driver for Ambiq clock control.
|
||||
138
drivers/clock_control/clock_control_ambiq.c
Normal file
138
drivers/clock_control/clock_control_ambiq.c
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2023 Ambiq Micro Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#define DT_DRV_COMPAT ambiq_clkctrl
|
||||
|
||||
#include <errno.h>
|
||||
#include <zephyr/init.h>
|
||||
#include <zephyr/drivers/clock_control.h>
|
||||
#include <zephyr/drivers/pinctrl.h>
|
||||
#include <zephyr/drivers/clock_control/clock_control_ambiq.h>
|
||||
#include <am_mcu_apollo.h>
|
||||
|
||||
#include <zephyr/logging/log.h>
|
||||
LOG_MODULE_REGISTER(clock_control_ambiq, CONFIG_CLOCK_CONTROL_LOG_LEVEL);
|
||||
|
||||
struct ambiq_clock_config {
|
||||
uint32_t clock_freq;
|
||||
const struct pinctrl_dev_config *pcfg;
|
||||
};
|
||||
|
||||
static int ambiq_clock_on(const struct device *dev, clock_control_subsys_t sub_system)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
int ret;
|
||||
uint32_t clock_name = (uint32_t)sub_system;
|
||||
am_hal_mcuctrl_control_arg_t arg = {
|
||||
.b_arg_hfxtal_in_use = true,
|
||||
.b_arg_apply_ext_source = false,
|
||||
.b_arg_force_update = false,
|
||||
};
|
||||
|
||||
if (clock_name >= CLOCK_CONTROL_AMBIQ_TYPE_MAX) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (clock_name) {
|
||||
case CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE:
|
||||
arg.ui32_arg_hfxtal_user_mask = BIT(AM_HAL_HFXTAL_BLE_CONTROLLER_EN);
|
||||
arg.b_arg_enable_HfXtalClockout = true;
|
||||
ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32M_KICK_START, &arg);
|
||||
break;
|
||||
case CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL:
|
||||
ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_ENABLE, 0);
|
||||
default:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ambiq_clock_off(const struct device *dev, clock_control_subsys_t sub_system)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
int ret;
|
||||
uint32_t clock_name = (uint32_t)sub_system;
|
||||
am_hal_mcuctrl_control_arg_t arg = {
|
||||
.b_arg_hfxtal_in_use = true,
|
||||
.b_arg_apply_ext_source = false,
|
||||
.b_arg_force_update = false,
|
||||
};
|
||||
|
||||
if (clock_name >= CLOCK_CONTROL_AMBIQ_TYPE_MAX) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
switch (clock_name) {
|
||||
case CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE:
|
||||
arg.ui32_arg_hfxtal_user_mask = BIT(AM_HAL_HFXTAL_BLE_CONTROLLER_EN);
|
||||
arg.b_arg_enable_HfXtalClockout = true;
|
||||
ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32M_DISABLE, &arg);
|
||||
break;
|
||||
case CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL:
|
||||
ret = am_hal_mcuctrl_control(AM_HAL_MCUCTRL_CONTROL_EXTCLK32K_DISABLE, 0);
|
||||
break;
|
||||
default:
|
||||
ret = -ENOTSUP;
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int ambiq_clock_get_rate(const struct device *dev, clock_control_subsys_t sub_system,
|
||||
uint32_t *rate)
|
||||
{
|
||||
ARG_UNUSED(sub_system);
|
||||
|
||||
const struct ambiq_clock_config *cfg = dev->config;
|
||||
*rate = cfg->clock_freq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int ambiq_clock_configure(const struct device *dev, clock_control_subsys_t sub_system,
|
||||
void *data)
|
||||
{
|
||||
ARG_UNUSED(sub_system);
|
||||
ARG_UNUSED(data);
|
||||
|
||||
const struct ambiq_clock_config *cfg = dev->config;
|
||||
int ret;
|
||||
|
||||
ret = pinctrl_apply_state(cfg->pcfg, PINCTRL_STATE_DEFAULT);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int ambiq_clock_init(const struct device *dev)
|
||||
{
|
||||
ARG_UNUSED(dev);
|
||||
|
||||
/* Nothing to do.*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clock_control_driver_api ambiq_clock_driver_api = {
|
||||
.on = ambiq_clock_on,
|
||||
.off = ambiq_clock_off,
|
||||
.get_rate = ambiq_clock_get_rate,
|
||||
.configure = ambiq_clock_configure,
|
||||
};
|
||||
|
||||
#define AMBIQ_CLOCK_INIT(n) \
|
||||
PINCTRL_DT_INST_DEFINE(n); \
|
||||
static const struct ambiq_clock_config ambiq_clock_config##n = { \
|
||||
.clock_freq = DT_INST_PROP(n, clock_frequency), \
|
||||
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(n)}; \
|
||||
DEVICE_DT_INST_DEFINE(n, ambiq_clock_init, NULL, NULL, &ambiq_clock_config##n, \
|
||||
POST_KERNEL, CONFIG_CLOCK_CONTROL_INIT_PRIORITY, \
|
||||
&ambiq_clock_driver_api);
|
||||
|
||||
DT_INST_FOREACH_STATUS_OKAY(AMBIQ_CLOCK_INIT)
|
||||
23
dts/bindings/clock/ambiq,clkctrl.yaml
Normal file
23
dts/bindings/clock/ambiq,clkctrl.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
# Copyright (c) 2023 Ambiq Micro Inc.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
description: Ambiq Apollo Series SoC Clock Controller
|
||||
|
||||
compatible: "ambiq,clkctrl"
|
||||
|
||||
include: [clock-controller.yaml, pinctrl-device.yaml, base.yaml]
|
||||
|
||||
properties:
|
||||
clock-frequency:
|
||||
type: int
|
||||
description: output clock frequency (Hz)
|
||||
required: true
|
||||
|
||||
pinctrl-0:
|
||||
required: true
|
||||
|
||||
pinctrl-names:
|
||||
required: true
|
||||
|
||||
"#clock-cells":
|
||||
const: 1
|
||||
37
include/zephyr/drivers/clock_control/clock_control_ambiq.h
Normal file
37
include/zephyr/drivers/clock_control/clock_control_ambiq.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2023 Ambiq Micro Inc.
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#ifndef ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_CLOCK_CONTROL_AMBIQ_H_
|
||||
#define ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_CLOCK_CONTROL_AMBIQ_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/** @brief Clocks handled by the CLOCK peripheral.
|
||||
*
|
||||
* Enum shall be used as a sys argument in clock_control API.
|
||||
*/
|
||||
enum clock_control_ambiq_type {
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_BLE,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_USB,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_ADC,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HFXTAL_AUADC,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_DBGCTRL,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_CLKGEN_MISC,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_CLKGEN_CLKOUT,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_PDM,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_IIS,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_HCXTAL_IOM,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_LFXTAL,
|
||||
CLOCK_CONTROL_AMBIQ_TYPE_MAX
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ZEPHYR_INCLUDE_DRIVERS_CLOCK_CONTROL_CLOCK_CONTROL_AMBIQ_H_ */
|
||||
Reference in New Issue
Block a user