1 /*
2  * Copyright (c) 2024 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <internal/nrfs_backend.h>
8 #include <internal/nrfs_callbacks.h>
9 #include <nrfs_clock.h>
10 
11 typedef struct {
12 	nrfs_clock_evt_handler_t handler;
13 	bool is_initialized;
14 } nrfs_clock_cb_t;
15 static nrfs_clock_cb_t m_cb;
16 
nrfs_clock_service_notify(void * p_notification,size_t size)17 void nrfs_clock_service_notify(void *p_notification, size_t size)
18 {
19 	if (!m_cb.handler || !m_cb.is_initialized) {
20 		return;
21 	}
22 
23 	nrfs_clock_evt_t evt;
24 	nrfs_generic_t *p_data = (nrfs_generic_t *)p_notification;
25 
26 	if (NRFS_HDR_FILTER_ERR_GET(&p_data->hdr)) {
27 		evt.type = NRFS_CLOCK_EVT_REJECT;
28 		m_cb.handler(&evt, (void *)p_data->ctx.ctx);
29 		return;
30 	}
31 
32 	nrfs_clock_rsp_t *p_rsp = (nrfs_clock_rsp_t *)p_notification;
33 
34 	evt.data		= p_rsp->data;
35 	switch (p_data->hdr.req) {
36 	case NRFS_CLOCK_REQ_SUBSCRIBE:
37 		evt.type = NRFS_CLOCK_EVT_CHANGE;
38 		m_cb.handler(&evt, (void *)p_rsp->ctx.ctx);
39 		break;
40 
41 	case NRFS_CLOCK_REQ_LFCLK_SRC:
42 	case NRFS_CLOCK_REQ_HSFLL_MODE:
43 		evt.type = NRFS_CLOCK_EVT_APPLIED;
44 		m_cb.handler(&evt, (void *)p_rsp->ctx.ctx);
45 		break;
46 
47 	default:
48 		break;
49 	}
50 }
51 
nrfs_clock_init(nrfs_clock_evt_handler_t handler)52 nrfs_err_t nrfs_clock_init(nrfs_clock_evt_handler_t handler)
53 {
54 	if (m_cb.is_initialized) {
55 		return NRFS_ERR_INVALID_STATE;
56 	}
57 
58 	m_cb.handler	    = handler;
59 	m_cb.is_initialized = true;
60 	return NRFS_SUCCESS;
61 }
62 
nrfs_clock_uninit(void)63 void nrfs_clock_uninit(void)
64 {
65 	m_cb.is_initialized = false;
66 }
67 
nrfs_clock_subscribe(uint8_t event_mask,void * p_context)68 nrfs_err_t nrfs_clock_subscribe(uint8_t event_mask, void *p_context)
69 {
70 	if (!m_cb.is_initialized) {
71 		return NRFS_ERR_INVALID_STATE;
72 	}
73 
74 	nrfs_clock_subscribe_t req;
75 
76 	NRFS_SERVICE_HDR_FILL(&req, NRFS_CLOCK_REQ_SUBSCRIBE);
77 	req.ctx.ctx    = (uint32_t)p_context;
78 	req.event_mask = event_mask;
79 
80 	return nrfs_backend_send(&req, sizeof(req));
81 }
82 
nrfs_clock_unsubscribe(void)83 nrfs_err_t nrfs_clock_unsubscribe(void)
84 {
85 	if (!m_cb.is_initialized) {
86 		return NRFS_ERR_INVALID_STATE;
87 	}
88 
89 	nrfs_clock_subscribe_t req;
90 
91 	NRFS_SERVICE_HDR_FILL(&req, NRFS_CLOCK_REQ_UNSUBSCRIBE);
92 
93 	return nrfs_backend_send(&req, sizeof(req));
94 }
95 
nrfs_clock_lfclk_src_set(nrfs_clock_src_t src,void * p_context)96 nrfs_err_t nrfs_clock_lfclk_src_set(nrfs_clock_src_t src, void *p_context)
97 {
98 	if (!m_cb.is_initialized) {
99 		return NRFS_ERR_INVALID_STATE;
100 	}
101 
102 	nrfs_clock_lfclk_src_req_t req;
103 
104 	NRFS_SERVICE_HDR_FILL(&req, NRFS_CLOCK_REQ_LFCLK_SRC);
105 	req.src	    = src;
106 	req.ctx.ctx = (uint32_t)p_context;
107 
108 	return nrfs_backend_send(&req, sizeof(req));
109 }
110 
nrfs_clock_lfclk_src_set_no_rsp(nrfs_clock_src_t src,void * p_context)111 nrfs_err_t nrfs_clock_lfclk_src_set_no_rsp(nrfs_clock_src_t src, void *p_context)
112 {
113 	if (!m_cb.is_initialized) {
114 		return NRFS_ERR_INVALID_STATE;
115 	}
116 
117 	nrfs_clock_lfclk_src_req_t req;
118 
119 	NRFS_SERVICE_HDR_FILL(&req, NRFS_CLOCK_REQ_LFCLK_SRC);
120 	NRFS_HDR_NO_RSP_SET(&req.hdr);
121 	req.src	    = src;
122 	req.ctx.ctx = (uint32_t)p_context;
123 
124 	return nrfs_backend_send(&req, sizeof(req));
125 }
126 
nrfs_clock_hsfll_mode_set(const nrfs_clock_hsfll_mode_t mode,void * p_context)127 nrfs_err_t nrfs_clock_hsfll_mode_set(const nrfs_clock_hsfll_mode_t mode, void * p_context)
128 {
129 	if (!m_cb.is_initialized) {
130 		return NRFS_ERR_INVALID_STATE;
131 	}
132 
133 	nrfs_clock_hsfll_mode_req_t req;
134 
135 	NRFS_SERVICE_HDR_FILL(&req, NRFS_CLOCK_REQ_HSFLL_MODE);
136 	req.mode = mode;
137 	req.ctx.ctx = (uint32_t)p_context;
138 
139 	return nrfs_backend_send(&req, sizeof(req));
140 }
141 
nrfs_clock_hsfll_mode_set_no_rsp(const nrfs_clock_hsfll_mode_t mode,void * p_context)142 nrfs_err_t nrfs_clock_hsfll_mode_set_no_rsp(const nrfs_clock_hsfll_mode_t mode, void * p_context)
143 {
144 	if (!m_cb.is_initialized) {
145 		return NRFS_ERR_INVALID_STATE;
146 	}
147 
148 	nrfs_clock_hsfll_mode_req_t req;
149 
150 	NRFS_SERVICE_HDR_FILL(&req, NRFS_CLOCK_REQ_HSFLL_MODE);
151 	NRFS_HDR_NO_RSP_SET(&req.hdr);
152 	req.mode = mode;
153 	req.ctx.ctx = (uint32_t)p_context;
154 
155 	return nrfs_backend_send(&req, sizeof(req));
156 }
157