Skip to content

Commit c950c56

Browse files
bjarki-andreasenkartben
authored andcommitted
drivers: clock_control: nrf2_hsfll: impl resolve
Implement nrf_clock_control_resolve() API. Signed-off-by: Bjarki Arge Andreasen <[email protected]>
1 parent 9983222 commit c950c56

File tree

1 file changed

+60
-19
lines changed

1 file changed

+60
-19
lines changed

drivers/clock_control/clock_control_nrf2_hsfll.c

Lines changed: 60 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -100,35 +100,56 @@ static void hsfll_work_handler(struct k_work *work)
100100
k_timer_start(&dev_data->timer, NRFS_DVFS_TIMEOUT, K_NO_WAIT);
101101
}
102102

103-
static struct onoff_manager *hsfll_find_mgr(const struct device *dev,
104-
const struct nrf_clock_spec *spec)
103+
static int hsfll_resolve_spec_to_idx(const struct nrf_clock_spec *req_spec)
105104
{
106-
struct hsfll_dev_data *dev_data = dev->data;
107-
uint32_t frequency;
108-
109-
if (!spec) {
110-
return &dev_data->clk_cfg.onoff[0].mgr;
111-
}
105+
uint32_t req_frequency;
112106

113-
if (spec->accuracy || spec->precision) {
107+
if (req_spec->accuracy || req_spec->precision) {
114108
LOG_ERR("invalid specification of accuracy or precision");
115-
return NULL;
109+
return -EINVAL;
116110
}
117111

118-
frequency = spec->frequency == NRF_CLOCK_CONTROL_FREQUENCY_MAX
119-
? HSFLL_FREQ_HIGH
120-
: spec->frequency;
112+
req_frequency = req_spec->frequency == NRF_CLOCK_CONTROL_FREQUENCY_MAX
113+
? HSFLL_FREQ_HIGH
114+
: req_spec->frequency;
121115

122116
for (int i = 0; i < ARRAY_SIZE(clock_options); ++i) {
123-
if (frequency > clock_options[i].frequency) {
117+
if (req_frequency > clock_options[i].frequency) {
124118
continue;
125119
}
126120

127-
return &dev_data->clk_cfg.onoff[i].mgr;
121+
return i;
128122
}
129123

130124
LOG_ERR("invalid frequency");
131-
return NULL;
125+
return -EINVAL;
126+
}
127+
128+
static void hsfll_get_spec_by_idx(uint8_t idx, struct nrf_clock_spec *spec)
129+
{
130+
spec->frequency = clock_options[idx].frequency;
131+
spec->accuracy = 0;
132+
spec->precision = 0;
133+
}
134+
135+
static struct onoff_manager *hsfll_get_mgr_by_idx(const struct device *dev, uint8_t idx)
136+
{
137+
struct hsfll_dev_data *dev_data = dev->data;
138+
139+
return &dev_data->clk_cfg.onoff[idx].mgr;
140+
}
141+
142+
static struct onoff_manager *hsfll_find_mgr_by_spec(const struct device *dev,
143+
const struct nrf_clock_spec *spec)
144+
{
145+
int idx;
146+
147+
if (!spec) {
148+
return hsfll_get_mgr_by_idx(dev, 0);
149+
}
150+
151+
idx = hsfll_resolve_spec_to_idx(spec);
152+
return idx < 0 ? NULL : hsfll_get_mgr_by_idx(dev, idx);
132153
}
133154
#endif /* CONFIG_NRFS_DVFS_LOCAL_DOMAIN */
134155

@@ -137,7 +158,7 @@ static int api_request_hsfll(const struct device *dev,
137158
struct onoff_client *cli)
138159
{
139160
#ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN
140-
struct onoff_manager *mgr = hsfll_find_mgr(dev, spec);
161+
struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec);
141162

142163
if (mgr) {
143164
return clock_config_request(mgr, cli);
@@ -153,7 +174,7 @@ static int api_release_hsfll(const struct device *dev,
153174
const struct nrf_clock_spec *spec)
154175
{
155176
#ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN
156-
struct onoff_manager *mgr = hsfll_find_mgr(dev, spec);
177+
struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec);
157178

158179
if (mgr) {
159180
return onoff_release(mgr);
@@ -170,7 +191,7 @@ static int api_cancel_or_release_hsfll(const struct device *dev,
170191
struct onoff_client *cli)
171192
{
172193
#ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN
173-
struct onoff_manager *mgr = hsfll_find_mgr(dev, spec);
194+
struct onoff_manager *mgr = hsfll_find_mgr_by_spec(dev, spec);
174195

175196
if (mgr) {
176197
return onoff_cancel_or_release(mgr, cli);
@@ -182,6 +203,25 @@ static int api_cancel_or_release_hsfll(const struct device *dev,
182203
#endif
183204
}
184205

206+
static int api_resolve_hsfll(const struct device *dev,
207+
const struct nrf_clock_spec *req_spec,
208+
struct nrf_clock_spec *res_spec)
209+
{
210+
#ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN
211+
int idx;
212+
213+
idx = hsfll_resolve_spec_to_idx(req_spec);
214+
if (idx < 0) {
215+
return -EINVAL;
216+
}
217+
218+
hsfll_get_spec_by_idx(idx, res_spec);
219+
return 0;
220+
#else
221+
return -ENOTSUP;
222+
#endif
223+
}
224+
185225
static int hsfll_init(const struct device *dev)
186226
{
187227
#ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN
@@ -212,6 +252,7 @@ static DEVICE_API(nrf_clock_control, hsfll_drv_api) = {
212252
.request = api_request_hsfll,
213253
.release = api_release_hsfll,
214254
.cancel_or_release = api_cancel_or_release_hsfll,
255+
.resolve = api_resolve_hsfll,
215256
};
216257

217258
#ifdef CONFIG_NRFS_DVFS_LOCAL_DOMAIN

0 commit comments

Comments
 (0)