Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
132 changes: 110 additions & 22 deletions drivers/clock_control/clock_control_nrf2_fll16m.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#define FLL16M_HFXO_ACCURACY DT_PROP(FLL16M_HFXO_NODE, accuracy_ppm)
#define FLL16M_OPEN_LOOP_ACCURACY DT_INST_PROP(0, open_loop_accuracy_ppm)
#define FLL16M_MAX_ACCURACY FLL16M_HFXO_ACCURACY
#define FLL16M_OPEN_LOOP_STARTUP_TIME_US DT_INST_PROP(0, open_loop_startup_time_us)

#define BICR (NRF_BICR_Type *)DT_REG_ADDR(DT_NODELABEL(bicr))

Expand All @@ -57,6 +58,7 @@
STRUCT_CLOCK_CONFIG(fll16m, ARRAY_SIZE(clock_options)) clk_cfg;
struct onoff_client hfxo_cli;
sys_snode_t fll16m_node;
uint32_t bypass_startup_time_us;
};

struct fll16m_dev_config {
Expand Down Expand Up @@ -133,49 +135,98 @@
}
}

static struct onoff_manager *fll16m_find_mgr(const struct device *dev,
const struct nrf_clock_spec *spec)
static int fll16m_resolve_spec_to_idx(const struct device *dev,
const struct nrf_clock_spec *req_spec)
{
struct fll16m_dev_data *dev_data = dev->data;
const struct fll16m_dev_config *dev_config = dev->config;
uint16_t accuracy;

if (!spec) {
return &dev_data->clk_cfg.onoff[0].mgr;
}
uint16_t req_accuracy;

if (spec->frequency > dev_config->fixed_frequency) {
if (req_spec->frequency > dev_config->fixed_frequency) {
LOG_ERR("invalid frequency");
return NULL;
return -EINVAL;
}

if (spec->precision) {
if (req_spec->precision) {
LOG_ERR("invalid precision");
return NULL;
return -EINVAL;
}

accuracy = spec->accuracy == NRF_CLOCK_CONTROL_ACCURACY_MAX
? FLL16M_MAX_ACCURACY
: spec->accuracy;
req_accuracy = req_spec->accuracy == NRF_CLOCK_CONTROL_ACCURACY_MAX
? FLL16M_MAX_ACCURACY
: req_spec->accuracy;

for (int i = 0; i < ARRAY_SIZE(clock_options); ++i) {
if (accuracy &&
accuracy < clock_options[i].accuracy) {
if (req_accuracy &&
req_accuracy < clock_options[i].accuracy) {
continue;

Check notice on line 161 in drivers/clock_control/clock_control_nrf2_fll16m.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_fll16m.c:161 - req_accuracy = req_spec->accuracy == NRF_CLOCK_CONTROL_ACCURACY_MAX - ? FLL16M_MAX_ACCURACY - : req_spec->accuracy; + req_accuracy = req_spec->accuracy == NRF_CLOCK_CONTROL_ACCURACY_MAX ? FLL16M_MAX_ACCURACY + : req_spec->accuracy; for (int i = 0; i < ARRAY_SIZE(clock_options); ++i) { - if (req_accuracy && - req_accuracy < clock_options[i].accuracy) { + if (req_accuracy && req_accuracy < clock_options[i].accuracy) {
}

return &dev_data->clk_cfg.onoff[i].mgr;
return i;
}

LOG_ERR("invalid accuracy");
return NULL;
return -EINVAL;
}

static void fll16m_get_spec_by_idx(const struct device *dev,
uint8_t idx,
struct nrf_clock_spec *spec)

Check notice on line 173 in drivers/clock_control/clock_control_nrf2_fll16m.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_fll16m.c:173 -static void fll16m_get_spec_by_idx(const struct device *dev, - uint8_t idx, +static void fll16m_get_spec_by_idx(const struct device *dev, uint8_t idx,
{
const struct fll16m_dev_config *dev_config = dev->config;

spec->frequency = dev_config->fixed_frequency;
spec->accuracy = clock_options[idx].accuracy;
spec->precision = NRF_CLOCK_CONTROL_PRECISION_DEFAULT;
}

static int fll16m_get_startup_time_by_idx(const struct device *dev,
uint8_t idx,
uint32_t *startup_time_us)

Check notice on line 184 in drivers/clock_control/clock_control_nrf2_fll16m.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_fll16m.c:184 -static int fll16m_get_startup_time_by_idx(const struct device *dev, - uint8_t idx, +static int fll16m_get_startup_time_by_idx(const struct device *dev, uint8_t idx,
{
const struct fll16m_dev_data *dev_data = dev->data;
uint8_t mode = clock_options[idx].mode;

switch (mode) {
case FLL16M_MODE_OPEN_LOOP:
*startup_time_us = FLL16M_OPEN_LOOP_STARTUP_TIME_US;
return 0;

case FLL16M_MODE_BYPASS:
*startup_time_us = dev_data->bypass_startup_time_us;
return 0;

default:
break;
}

return -EINVAL;
}

static struct onoff_manager *fll16m_get_mgr_by_idx(const struct device *dev, uint8_t idx)
{
struct fll16m_dev_data *dev_data = dev->data;

return &dev_data->clk_cfg.onoff[idx].mgr;
}

static struct onoff_manager *fll16m_find_mgr_by_spec(const struct device *dev,
const struct nrf_clock_spec *spec)
{
int idx;

if (!spec) {
return fll16m_get_mgr_by_idx(dev, 0);
}

idx = fll16m_resolve_spec_to_idx(dev, spec);
return idx < 0 ? NULL : fll16m_get_mgr_by_idx(dev, idx);
}

static int api_request_fll16m(const struct device *dev,
const struct nrf_clock_spec *spec,
struct onoff_client *cli)
{
struct onoff_manager *mgr = fll16m_find_mgr(dev, spec);
struct onoff_manager *mgr = fll16m_find_mgr_by_spec(dev, spec);

if (mgr) {
return clock_config_request(mgr, cli);
Expand All @@ -187,7 +238,7 @@
static int api_release_fll16m(const struct device *dev,
const struct nrf_clock_spec *spec)
{
struct onoff_manager *mgr = fll16m_find_mgr(dev, spec);
struct onoff_manager *mgr = fll16m_find_mgr_by_spec(dev, spec);

if (mgr) {
return onoff_release(mgr);
Expand All @@ -200,7 +251,7 @@
const struct nrf_clock_spec *spec,
struct onoff_client *cli)
{
struct onoff_manager *mgr = fll16m_find_mgr(dev, spec);
struct onoff_manager *mgr = fll16m_find_mgr_by_spec(dev, spec);

if (mgr) {
return onoff_cancel_or_release(mgr, cli);
Expand All @@ -222,10 +273,45 @@
return 0;
}

static int api_resolve(const struct device *dev,
const struct nrf_clock_spec *req_spec,
struct nrf_clock_spec *res_spec)

Check notice on line 278 in drivers/clock_control/clock_control_nrf2_fll16m.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_fll16m.c:278 -static int api_resolve(const struct device *dev, - const struct nrf_clock_spec *req_spec, +static int api_resolve(const struct device *dev, const struct nrf_clock_spec *req_spec,
{
int idx;

idx = fll16m_resolve_spec_to_idx(dev, req_spec);
if (idx < 0) {
return -EINVAL;
}

fll16m_get_spec_by_idx(dev, idx, res_spec);
return 0;
}

static int api_get_startup_time(const struct device *dev,
const struct nrf_clock_spec *spec,
uint32_t *startup_time_us)

Check notice on line 293 in drivers/clock_control/clock_control_nrf2_fll16m.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_fll16m.c:293 -static int api_get_startup_time(const struct device *dev, - const struct nrf_clock_spec *spec, +static int api_get_startup_time(const struct device *dev, const struct nrf_clock_spec *spec,
{
int idx;

idx = fll16m_resolve_spec_to_idx(dev, spec);
if (idx < 0) {
return -EINVAL;
}

return fll16m_get_startup_time_by_idx(dev, idx, startup_time_us);
}

static int fll16m_init(const struct device *dev)
{
struct fll16m_dev_data *dev_data = dev->data;

dev_data->bypass_startup_time_us = nrf_bicr_hfxo_startup_time_us_get(BICR);
if (dev_data->bypass_startup_time_us == NRF_BICR_HFXO_STARTUP_TIME_UNCONFIGURED) {
LOG_ERR("BICR HFXO startup time invalid");
return -ENODEV;
}

return clock_config_init(&dev_data->clk_cfg,
ARRAY_SIZE(dev_data->clk_cfg.onoff),
fll16m_work_handler);
Expand All @@ -237,9 +323,11 @@
.off = api_nosys_on_off,
.get_rate = api_get_rate_fll16m,
},
.request = api_request_fll16m,

Check notice on line 326 in drivers/clock_control/clock_control_nrf2_fll16m.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_fll16m.c:326 - .std_api = { - .on = api_nosys_on_off, - .off = api_nosys_on_off, - .get_rate = api_get_rate_fll16m, - }, + .std_api = + { + .on = api_nosys_on_off, + .off = api_nosys_on_off, + .get_rate = api_get_rate_fll16m, + },
.release = api_release_fll16m,
.cancel_or_release = api_cancel_or_release_fll16m,
.resolve = api_resolve,
.get_startup_time = api_get_startup_time,
};

static struct fll16m_dev_data fll16m_data;
Expand Down
80 changes: 61 additions & 19 deletions drivers/clock_control/clock_control_nrf2_global_hsfll.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,43 +62,69 @@
return dev_config->clock_frequencies[ARRAY_SIZE(dev_config->clock_frequencies) - 1];
}

static struct onoff_manager *global_hsfll_find_mgr(const struct device *dev,
const struct nrf_clock_spec *spec)
static int global_hsfll_resolve_spec_to_idx(const struct device *dev,
const struct nrf_clock_spec *req_spec)
{
struct global_hsfll_dev_data *dev_data = dev->data;
const struct global_hsfll_dev_config *dev_config = dev->config;
uint32_t frequency;

if (!spec) {
return &dev_data->clk_cfg.onoff[0].mgr;
}
uint32_t req_frequency;

if (spec->accuracy || spec->precision) {
if (req_spec->accuracy || req_spec->precision) {
LOG_ERR("invalid specification of accuracy or precision");
return NULL;
return -EINVAL;
}

frequency = spec->frequency == NRF_CLOCK_CONTROL_FREQUENCY_MAX
? global_hsfll_get_max_clock_frequency(dev)
: spec->frequency;
req_frequency = req_spec->frequency == NRF_CLOCK_CONTROL_FREQUENCY_MAX
? global_hsfll_get_max_clock_frequency(dev)
: req_spec->frequency;

Check notice on line 79 in drivers/clock_control/clock_control_nrf2_global_hsfll.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_global_hsfll.c:79 - ? global_hsfll_get_max_clock_frequency(dev) - : req_spec->frequency; + ? global_hsfll_get_max_clock_frequency(dev) + : req_spec->frequency;
for (uint8_t i = 0; i < ARRAY_SIZE(dev_config->clock_frequencies); i++) {
if (dev_config->clock_frequencies[i] < frequency) {
if (dev_config->clock_frequencies[i] < req_frequency) {
continue;
}

return &dev_data->clk_cfg.onoff[i].mgr;
return i;
}

LOG_ERR("invalid frequency");
return NULL;
return -EINVAL;
}

static void global_hsfll_get_spec_by_idx(const struct device *dev,
uint8_t idx,
struct nrf_clock_spec *spec)

Check notice on line 94 in drivers/clock_control/clock_control_nrf2_global_hsfll.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_global_hsfll.c:94 -static void global_hsfll_get_spec_by_idx(const struct device *dev, - uint8_t idx, +static void global_hsfll_get_spec_by_idx(const struct device *dev, uint8_t idx,
{
const struct global_hsfll_dev_config *dev_config = dev->config;

spec->frequency = dev_config->clock_frequencies[idx];
spec->accuracy = 0;
spec->precision = 0;
}

static struct onoff_manager *global_hsfll_get_mgr_by_idx(const struct device *dev, uint8_t idx)
{
struct global_hsfll_dev_data *dev_data = dev->data;

return &dev_data->clk_cfg.onoff[idx].mgr;
}

static struct onoff_manager *global_hsfll_find_mgr_by_spec(const struct device *dev,
const struct nrf_clock_spec *spec)
{
int idx;

if (!spec) {
return global_hsfll_get_mgr_by_idx(dev, 0);
}

idx = global_hsfll_resolve_spec_to_idx(dev, spec);
return idx < 0 ? NULL : global_hsfll_get_mgr_by_idx(dev, idx);
}

static int api_request_global_hsfll(const struct device *dev,
const struct nrf_clock_spec *spec,
struct onoff_client *cli)
{
struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec);
struct onoff_manager *mgr = global_hsfll_find_mgr_by_spec(dev, spec);

if (mgr) {
return clock_config_request(mgr, cli);
Expand All @@ -110,7 +136,7 @@
static int api_release_global_hsfll(const struct device *dev,
const struct nrf_clock_spec *spec)
{
struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec);
struct onoff_manager *mgr = global_hsfll_find_mgr_by_spec(dev, spec);

if (mgr) {
return onoff_release(mgr);
Expand All @@ -123,7 +149,7 @@
const struct nrf_clock_spec *spec,
struct onoff_client *cli)
{
struct onoff_manager *mgr = global_hsfll_find_mgr(dev, spec);
struct onoff_manager *mgr = global_hsfll_find_mgr_by_spec(dev, spec);

if (mgr) {
return onoff_cancel_or_release(mgr, cli);
Expand All @@ -132,14 +158,30 @@
return -EINVAL;
}

static int api_resolve_global_hsfll(const struct device *dev,
const struct nrf_clock_spec *req_spec,
struct nrf_clock_spec *res_spec)

Check notice on line 163 in drivers/clock_control/clock_control_nrf2_global_hsfll.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_global_hsfll.c:163 -static int api_resolve_global_hsfll(const struct device *dev, - const struct nrf_clock_spec *req_spec, +static int api_resolve_global_hsfll(const struct device *dev, const struct nrf_clock_spec *req_spec,
{
int idx;

idx = global_hsfll_resolve_spec_to_idx(dev, req_spec);
if (idx < 0) {
return -EINVAL;
}

global_hsfll_get_spec_by_idx(dev, idx, res_spec);
return 0;
}

static DEVICE_API(nrf_clock_control, driver_api) = {
.std_api = {
.on = api_nosys_on_off,
.off = api_nosys_on_off,
},
.request = api_request_global_hsfll,

Check notice on line 181 in drivers/clock_control/clock_control_nrf2_global_hsfll.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

You may want to run clang-format on this change

drivers/clock_control/clock_control_nrf2_global_hsfll.c:181 - .std_api = { - .on = api_nosys_on_off, - .off = api_nosys_on_off, - }, + .std_api = + { + .on = api_nosys_on_off, + .off = api_nosys_on_off, + },
.release = api_release_global_hsfll,
.cancel_or_release = api_cancel_or_release_global_hsfll,
.resolve = api_resolve_global_hsfll,
};

static enum gdfs_frequency_setting global_hsfll_freq_idx_to_nrfs_freq(const struct device *dev,
Expand Down
35 changes: 35 additions & 0 deletions drivers/clock_control/clock_control_nrf2_hfxo.c
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,39 @@ static int init_hfxo(const struct device *dev)
return 0;
}

static int api_resolve(const struct device *dev,
const struct nrf_clock_spec *req_spec,
struct nrf_clock_spec *res_spec)
{
const struct dev_config_hfxo *dev_config = dev->config;

if (!is_clock_spec_valid(dev, req_spec)) {
return -EINVAL;
}

res_spec->frequency = dev_config->fixed_frequency;
res_spec->accuracy = dev_config->fixed_accuracy;
res_spec->precision = NRF_CLOCK_CONTROL_PRECISION_HIGH;
return 0;
}

static int api_get_startup_time(const struct device *dev,
const struct nrf_clock_spec *spec,
uint32_t *startup_time_us)
{
if (!is_clock_spec_valid(dev, spec)) {
return -EINVAL;
}

*startup_time_us = nrf_bicr_hfxo_startup_time_us_get(BICR);

if (*startup_time_us == NRF_BICR_HFXO_STARTUP_TIME_UNCONFIGURED) {
return -EINVAL;
}

return 0;
}

static DEVICE_API(nrf_clock_control, drv_api_hfxo) = {
.std_api = {
.on = api_nosys_on_off,
Expand All @@ -280,6 +313,8 @@ static DEVICE_API(nrf_clock_control, drv_api_hfxo) = {
.request = api_request_hfxo,
.release = api_release_hfxo,
.cancel_or_release = api_cancel_or_release_hfxo,
.resolve = api_resolve,
.get_startup_time = api_get_startup_time,
};

static struct dev_data_hfxo data_hfxo;
Expand Down
Loading
Loading