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_pmic.h>
10
11 typedef struct {
12 nrfs_pmic_evt_handler_t handler;
13 bool is_initialized;
14 } nrfs_pmic_cb_t;
15 static nrfs_pmic_cb_t m_cb;
16
nrfs_pmic_init(nrfs_pmic_evt_handler_t handler)17 nrfs_err_t nrfs_pmic_init(nrfs_pmic_evt_handler_t handler)
18 {
19 if (m_cb.is_initialized) {
20 return NRFS_ERR_INVALID_STATE;
21 }
22
23 m_cb.handler = handler;
24 m_cb.is_initialized = true;
25 return NRFS_SUCCESS;
26 }
27
nrfs_pmic_uninit(void)28 void nrfs_pmic_uninit(void)
29 {
30 m_cb.is_initialized = false;
31 }
32
nrfs_pmic_rffe_on(void * p_context)33 nrfs_err_t nrfs_pmic_rffe_on(void *p_context)
34 {
35 if (!m_cb.is_initialized) {
36 return NRFS_ERR_INVALID_STATE;
37 }
38
39 nrfs_pmic_rffe_on_req_t req;
40
41 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_RFFE_ON);
42 req.ctx.ctx = (uint32_t)p_context;
43
44 return nrfs_backend_send(&req, sizeof(req));
45 }
46
nrfs_pmic_rffe_on_no_rsp(void)47 nrfs_err_t nrfs_pmic_rffe_on_no_rsp(void)
48 {
49 if (!m_cb.is_initialized) {
50 return NRFS_ERR_INVALID_STATE;
51 }
52
53 nrfs_pmic_rffe_on_req_t req;
54
55 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_RFFE_ON);
56 NRFS_HDR_NO_RSP_SET(&req.hdr);
57
58 return nrfs_backend_send(&req, sizeof(req));
59 }
60
nrfs_pmic_rffe_off(void * p_context)61 nrfs_err_t nrfs_pmic_rffe_off(void *p_context)
62 {
63 if (!m_cb.is_initialized) {
64 return NRFS_ERR_INVALID_STATE;
65 }
66
67 nrfs_pmic_rffe_off_req_t req;
68
69 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_RFFE_OFF);
70 req.ctx.ctx = (uint32_t)p_context;
71
72 return nrfs_backend_send(&req, sizeof(req));
73 }
74
nrfs_pmic_rffe_off_no_rsp(void)75 nrfs_err_t nrfs_pmic_rffe_off_no_rsp(void)
76 {
77 if (!m_cb.is_initialized) {
78 return NRFS_ERR_INVALID_STATE;
79 }
80
81 nrfs_pmic_rffe_off_req_t req;
82
83 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_RFFE_OFF);
84 NRFS_HDR_NO_RSP_SET(&req.hdr);
85
86 return nrfs_backend_send(&req, sizeof(req));
87 }
88
nrfs_pmic_sim_on(pmic_sim_t sim,void * p_context)89 nrfs_err_t nrfs_pmic_sim_on(pmic_sim_t sim, void *p_context)
90 {
91 if (!m_cb.is_initialized) {
92 return NRFS_ERR_INVALID_STATE;
93 }
94
95 nrfs_pmic_sim_on_req_t req;
96
97 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_SIM_ON);
98 req.ctx.ctx = (uint32_t)p_context;
99 req.sim = sim;
100
101 return nrfs_backend_send(&req, sizeof(req));
102 }
103
nrfs_pmic_sim_on_no_rsp(pmic_sim_t sim)104 nrfs_err_t nrfs_pmic_sim_on_no_rsp(pmic_sim_t sim)
105 {
106 if (!m_cb.is_initialized) {
107 return NRFS_ERR_INVALID_STATE;
108 }
109
110 nrfs_pmic_sim_on_req_t req;
111
112 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_SIM_ON);
113 NRFS_HDR_NO_RSP_SET(&req.hdr);
114 req.sim = sim;
115
116 return nrfs_backend_send(&req, sizeof(req));
117 }
118
nrfs_pmic_sim_off(pmic_sim_t sim,void * p_context)119 nrfs_err_t nrfs_pmic_sim_off(pmic_sim_t sim, void *p_context)
120 {
121 if (!m_cb.is_initialized) {
122 return NRFS_ERR_INVALID_STATE;
123 }
124
125 nrfs_pmic_sim_off_req_t req;
126
127 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_SIM_OFF);
128 req.ctx.ctx = (uint32_t)p_context;
129 req.sim = sim;
130
131 return nrfs_backend_send(&req, sizeof(req));
132 }
133
nrfs_pmic_sim_off_no_rsp(pmic_sim_t sim)134 nrfs_err_t nrfs_pmic_sim_off_no_rsp(pmic_sim_t sim)
135 {
136 if (!m_cb.is_initialized) {
137 return NRFS_ERR_INVALID_STATE;
138 }
139
140 nrfs_pmic_sim_off_req_t req;
141
142 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_SIM_OFF);
143 NRFS_HDR_NO_RSP_SET(&req.hdr);
144 req.sim = sim;
145
146 return nrfs_backend_send(&req, sizeof(req));
147 }
148
nrfs_pmic_ble_radio_on(pmic_ble_radio_txpower_t txpower,void * p_context)149 nrfs_err_t nrfs_pmic_ble_radio_on(pmic_ble_radio_txpower_t txpower, void *p_context)
150 {
151 if (!m_cb.is_initialized) {
152 return NRFS_ERR_INVALID_STATE;
153 }
154
155 nrfs_pmic_ble_radio_on_req_t req;
156
157 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_BLE_RADIO_ON);
158 req.ctx.ctx = (uint32_t)p_context;
159 req.txpower = txpower;
160
161 return nrfs_backend_send(&req, sizeof(req));
162 }
163
nrfs_pmic_ble_radio_on_no_rsp(pmic_ble_radio_txpower_t txpower)164 nrfs_err_t nrfs_pmic_ble_radio_on_no_rsp(pmic_ble_radio_txpower_t txpower)
165 {
166 if (!m_cb.is_initialized) {
167 return NRFS_ERR_INVALID_STATE;
168 }
169
170 nrfs_pmic_ble_radio_on_req_t req;
171
172 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_BLE_RADIO_ON);
173 NRFS_HDR_NO_RSP_SET(&req.hdr);
174 req.txpower = txpower;
175
176 return nrfs_backend_send(&req, sizeof(req));
177 }
178
nrfs_pmic_ble_radio_off(void * p_context)179 nrfs_err_t nrfs_pmic_ble_radio_off(void *p_context)
180 {
181 if (!m_cb.is_initialized) {
182 return NRFS_ERR_INVALID_STATE;
183 }
184
185 nrfs_pmic_ble_radio_off_req_t req;
186
187 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_BLE_RADIO_OFF);
188 req.ctx.ctx = (uint32_t)p_context;
189
190 return nrfs_backend_send(&req, sizeof(req));
191 }
192
nrfs_pmic_ble_radio_off_no_rsp(void)193 nrfs_err_t nrfs_pmic_ble_radio_off_no_rsp(void)
194 {
195 if (!m_cb.is_initialized) {
196 return NRFS_ERR_INVALID_STATE;
197 }
198
199 nrfs_pmic_ble_radio_off_req_t req;
200
201 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_BLE_RADIO_OFF);
202 NRFS_HDR_NO_RSP_SET(&req.hdr);
203
204 return nrfs_backend_send(&req, sizeof(req));
205 }
206
nrfs_pmic_pwm_default_set(void * p_context)207 nrfs_err_t nrfs_pmic_pwm_default_set(void *p_context)
208 {
209 if (!m_cb.is_initialized) {
210 return NRFS_ERR_INVALID_STATE;
211 }
212
213 nrfs_pmic_pwm_default_req_t req;
214
215 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_PWM_DEFAULT);
216 req.ctx.ctx = (uint32_t)p_context;
217
218 return nrfs_backend_send(&req, sizeof(req));
219 }
220
nrfs_pmic_pwm_default_set_no_rsp(void)221 nrfs_err_t nrfs_pmic_pwm_default_set_no_rsp(void)
222 {
223 if (!m_cb.is_initialized) {
224 return NRFS_ERR_INVALID_STATE;
225 }
226
227 nrfs_pmic_pwm_default_req_t req;
228
229 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_PWM_DEFAULT);
230 NRFS_HDR_NO_RSP_SET(&req.hdr);
231
232 return nrfs_backend_send(&req, sizeof(req));
233 }
234
nrfs_pmic_pwm_ghost_avoid_set(void * p_context)235 nrfs_err_t nrfs_pmic_pwm_ghost_avoid_set(void *p_context)
236 {
237 if (!m_cb.is_initialized) {
238 return NRFS_ERR_INVALID_STATE;
239 }
240
241 nrfs_pmic_pwm_ghost_avoid_req_t req;
242
243 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_PWM_GHOST_AVOID);
244 req.ctx.ctx = (uint32_t)p_context;
245
246 return nrfs_backend_send(&req, sizeof(req));
247 }
248
nrfs_pmic_pwm_ghost_avoid_set_no_rsp(void)249 nrfs_err_t nrfs_pmic_pwm_ghost_avoid_set_no_rsp(void)
250 {
251 if (!m_cb.is_initialized) {
252 return NRFS_ERR_INVALID_STATE;
253 }
254
255 nrfs_pmic_pwm_ghost_avoid_req_t req;
256
257 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_PWM_GHOST_AVOID);
258 NRFS_HDR_NO_RSP_SET(&req.hdr);
259
260 return nrfs_backend_send(&req, sizeof(req));
261 }
262
nrfs_pmic_test_if_read(uint16_t addr,void * p_context)263 nrfs_err_t nrfs_pmic_test_if_read(uint16_t addr, void *p_context)
264 {
265 if (!m_cb.is_initialized) {
266 return NRFS_ERR_INVALID_STATE;
267 }
268
269 nrfs_pmic_test_if_req_t req;
270
271 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_TEST_IF);
272 req.ctx.ctx = (uint32_t)p_context;
273 req.reg.access_type = PMIC_REG_READ;
274 req.reg.addr = addr;
275 req.reg.val = 0;
276
277 return nrfs_backend_send(&req, sizeof(req));
278 }
279
nrfs_pmic_test_if_write(uint16_t addr,uint8_t val,void * p_context)280 nrfs_err_t nrfs_pmic_test_if_write(uint16_t addr, uint8_t val, void *p_context)
281 {
282 if (!m_cb.is_initialized) {
283 return NRFS_ERR_INVALID_STATE;
284 }
285
286 nrfs_pmic_test_if_req_t req;
287
288 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_TEST_IF);
289 req.ctx.ctx = (uint32_t)p_context;
290 req.reg.access_type = PMIC_REG_WRITE;
291 req.reg.addr = addr;
292 req.reg.val = val;
293
294 return nrfs_backend_send(&req, sizeof(req));
295 }
296
nrfs_pmic_info_read(void * p_context)297 nrfs_err_t nrfs_pmic_info_read(void *p_context)
298 {
299 if (!m_cb.is_initialized) {
300 return NRFS_ERR_INVALID_STATE;
301 }
302
303 nrfs_pmic_info_req_t req;
304
305 NRFS_SERVICE_HDR_FILL(&req, NRFS_PMIC_INFO);
306 req.ctx.ctx = (uint32_t)p_context;
307
308 return nrfs_backend_send(&req, sizeof(req));
309 }
310
nrfs_pmic_service_notify(void * p_notification,size_t size)311 void nrfs_pmic_service_notify(void *p_notification, size_t size)
312 {
313 if (!m_cb.handler || !m_cb.is_initialized) {
314 return;
315 }
316
317 nrfs_pmic_evt_t evt;
318 nrfs_generic_t *p_data = (nrfs_generic_t *)p_notification;
319
320 if (NRFS_HDR_FILTER_ERR_GET(&p_data->hdr)) {
321 evt.type = NRFS_PMIC_EVT_REJECT;
322 m_cb.handler(&evt, (void *)p_data->ctx.ctx);
323 return;
324 }
325
326 switch (p_data->hdr.req) {
327 case NRFS_PMIC_RFFE_ON:
328 case NRFS_PMIC_RFFE_OFF:
329 case NRFS_PMIC_SIM_ON:
330 case NRFS_PMIC_SIM_OFF:
331 case NRFS_PMIC_BLE_RADIO_ON:
332 case NRFS_PMIC_BLE_RADIO_OFF:
333 case NRFS_PMIC_PWM_DEFAULT:
334 case NRFS_PMIC_PWM_GHOST_AVOID:
335 evt.type = NRFS_PMIC_EVT_APPLIED;
336 m_cb.handler(&evt, (void *)p_data->ctx.ctx);
337 break;
338 case NRFS_PMIC_TEST_IF:
339 nrfs_pmic_rsp_t *p_rsp = (nrfs_pmic_rsp_t *)p_notification;
340
341 evt.type = NRFS_PMIC_EVT_TEST_IF_RSP;
342 evt.val = p_rsp->data.val;
343 evt.access_type = p_rsp->data.access_type;
344 m_cb.handler(&evt, (void *)p_rsp->ctx.ctx);
345 break;
346 case NRFS_PMIC_INFO:
347 nrfs_pmic_info_rsp_t *p_rsp_info = (nrfs_pmic_info_rsp_t *)p_notification;
348 nrfs_pmic_info_evt_t info_evt;
349
350 info_evt.type = NRFS_PMIC_EVT_INFO_RSP;
351 info_evt.info = p_rsp_info->data;
352 m_cb.handler(&info_evt, (void *)p_rsp_info->ctx.ctx);
353 break;
354 default:
355 break;
356 }
357 }
358