1 /*
2  * Copyright (c) 2021 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/audio/dmic.h>
8 #include <zephyr/drivers/clock_control/nrf_clock_control.h>
9 #include <zephyr/drivers/pinctrl.h>
10 #include <soc.h>
11 #include <dmm.h>
12 #include <nrfx_pdm.h>
13 
14 #include <zephyr/logging/log.h>
15 #include <zephyr/irq.h>
16 LOG_MODULE_REGISTER(dmic_nrfx_pdm, CONFIG_AUDIO_DMIC_LOG_LEVEL);
17 
18 #if CONFIG_SOC_SERIES_NRF54HX
19 #define DMIC_NRFX_CLOCK_FREQ 8*1000*1000UL
20 #else
21 #define DMIC_NRFX_CLOCK_FREQ 32*1000*1000UL
22 #endif
23 
24 struct dmic_nrfx_pdm_drv_data {
25 	const nrfx_pdm_t *pdm;
26 	struct onoff_manager *clk_mgr;
27 	struct onoff_client clk_cli;
28 	struct k_mem_slab *mem_slab;
29 	void *mem_slab_buffer;
30 	uint32_t block_size;
31 	struct k_msgq rx_queue;
32 	bool request_clock : 1;
33 	bool configured    : 1;
34 	volatile bool active;
35 	volatile bool stopping;
36 };
37 
38 struct dmic_nrfx_pdm_drv_cfg {
39 	nrfx_pdm_event_handler_t event_handler;
40 	nrfx_pdm_config_t nrfx_def_cfg;
41 	const struct pinctrl_dev_config *pcfg;
42 	enum clock_source {
43 		PCLK32M,
44 		PCLK32M_HFXO,
45 		ACLK
46 	} clk_src;
47 	void *mem_reg;
48 };
49 
free_buffer(struct dmic_nrfx_pdm_drv_data * drv_data)50 static void free_buffer(struct dmic_nrfx_pdm_drv_data *drv_data)
51 {
52 	k_mem_slab_free(drv_data->mem_slab, drv_data->mem_slab_buffer);
53 	LOG_DBG("Freed buffer %p", drv_data->mem_slab_buffer);
54 }
55 
stop_pdm(struct dmic_nrfx_pdm_drv_data * drv_data)56 static void stop_pdm(struct dmic_nrfx_pdm_drv_data *drv_data)
57 {
58 	drv_data->stopping = true;
59 	nrfx_pdm_stop(drv_data->pdm);
60 }
61 
event_handler(const struct device * dev,const nrfx_pdm_evt_t * evt)62 static void event_handler(const struct device *dev, const nrfx_pdm_evt_t *evt)
63 {
64 	struct dmic_nrfx_pdm_drv_data *drv_data = dev->data;
65 	const struct dmic_nrfx_pdm_drv_cfg *drv_cfg = dev->config;
66 	int ret;
67 	bool stop = false;
68 
69 	if (evt->buffer_requested) {
70 		void *buffer;
71 		nrfx_err_t err;
72 
73 		ret = k_mem_slab_alloc(drv_data->mem_slab, &drv_data->mem_slab_buffer, K_NO_WAIT);
74 		if (ret < 0) {
75 			LOG_ERR("Failed to allocate buffer: %d", ret);
76 			stop = true;
77 		} else {
78 			ret = dmm_buffer_in_prepare(drv_cfg->mem_reg, drv_data->mem_slab_buffer,
79 						    drv_data->block_size, &buffer);
80 			if (ret < 0) {
81 				LOG_ERR("Failed to prepare buffer: %d", ret);
82 				stop_pdm(drv_data);
83 				return;
84 			}
85 			err = nrfx_pdm_buffer_set(drv_data->pdm, buffer, drv_data->block_size / 2);
86 			if (err != NRFX_SUCCESS) {
87 				LOG_ERR("Failed to set buffer: 0x%08x", err);
88 				stop = true;
89 			}
90 		}
91 	}
92 
93 	if (drv_data->stopping) {
94 		if (evt->buffer_released) {
95 			ret = dmm_buffer_in_release(drv_cfg->mem_reg, drv_data->mem_slab_buffer,
96 						    drv_data->block_size, evt->buffer_released);
97 			if (ret < 0) {
98 				LOG_ERR("Failed to release buffer: %d", ret);
99 				stop_pdm(drv_data);
100 				return;
101 			}
102 			free_buffer(drv_data);
103 		}
104 
105 		if (drv_data->active) {
106 			drv_data->active = false;
107 			if (drv_data->request_clock) {
108 				(void)onoff_release(drv_data->clk_mgr);
109 			}
110 		}
111 	} else if (evt->buffer_released) {
112 		ret = dmm_buffer_in_release(drv_cfg->mem_reg, drv_data->mem_slab_buffer,
113 					    drv_data->block_size, evt->buffer_released);
114 		if (ret < 0) {
115 			LOG_ERR("Failed to release buffer: %d", ret);
116 			stop_pdm(drv_data);
117 			return;
118 		}
119 		ret = k_msgq_put(&drv_data->rx_queue,
120 				 &drv_data->mem_slab_buffer,
121 				 K_NO_WAIT);
122 		if (ret < 0) {
123 			LOG_ERR("No room in RX queue");
124 			stop = true;
125 			free_buffer(drv_data);
126 		} else {
127 			LOG_DBG("Queued buffer %p", evt->buffer_released);
128 		}
129 	}
130 	if (stop) {
131 		stop_pdm(drv_data);
132 	}
133 }
134 
is_in_freq_range(uint32_t freq,const struct dmic_cfg * pdm_cfg)135 static bool is_in_freq_range(uint32_t freq, const struct dmic_cfg *pdm_cfg)
136 {
137 	return freq >= pdm_cfg->io.min_pdm_clk_freq && freq <= pdm_cfg->io.max_pdm_clk_freq;
138 }
139 
is_better(uint32_t freq,uint8_t ratio,uint32_t req_rate,uint32_t * best_diff,uint32_t * best_rate,uint32_t * best_freq)140 static bool is_better(uint32_t freq,
141 		      uint8_t ratio,
142 		      uint32_t req_rate,
143 		      uint32_t *best_diff,
144 		      uint32_t *best_rate,
145 		      uint32_t *best_freq)
146 {
147 	uint32_t act_rate = freq / ratio;
148 	uint32_t diff = act_rate >= req_rate ? (act_rate - req_rate)
149 					     : (req_rate - act_rate);
150 
151 	LOG_DBG("Freq %u, ratio %u, act_rate %u", freq, ratio, act_rate);
152 
153 	if (diff < *best_diff) {
154 		*best_diff = diff;
155 		*best_rate = act_rate;
156 		*best_freq = freq;
157 		return true;
158 	}
159 
160 	return false;
161 }
162 
check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg * drv_cfg,nrfx_pdm_config_t * config,const struct dmic_cfg * pdm_cfg,uint8_t ratio,uint32_t * best_diff,uint32_t * best_rate,uint32_t * best_freq)163 static bool check_pdm_frequencies(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
164 				  nrfx_pdm_config_t *config,
165 				  const struct dmic_cfg *pdm_cfg,
166 				  uint8_t ratio,
167 				  uint32_t *best_diff,
168 				  uint32_t *best_rate,
169 				  uint32_t *best_freq)
170 {
171 	uint32_t req_rate = pdm_cfg->streams[0].pcm_rate;
172 	bool better_found = false;
173 
174 #if NRF_PDM_HAS_PRESCALER
175 	uint32_t src_freq = 32 * 1000 * 1000UL;
176 	uint32_t req_freq = req_rate * ratio;
177 	uint32_t prescaler = src_freq / req_freq;
178 	uint32_t act_freq = src_freq / prescaler;
179 
180 	if (is_in_freq_range(act_freq, pdm_cfg) &&
181 	    is_better(act_freq, ratio, req_rate, best_diff, best_rate, best_freq)) {
182 		config->prescaler = prescaler;
183 
184 		better_found = true;
185 	}
186 
187 	/* Stop if an exact rate match is found. */
188 	if (*best_diff == 0) {
189 		return true;
190 	}
191 
192 	/* Prescaler value is rounded down by default,
193 	 * thus value rounded up should be checked as well.
194 	 */
195 	prescaler += 1;
196 	act_freq  = src_freq / prescaler;
197 
198 	if (is_in_freq_range(act_freq, pdm_cfg) &&
199 	    is_better(act_freq, ratio, req_rate, best_diff, best_rate, best_freq)) {
200 		config->prescaler = prescaler;
201 
202 		better_found = true;
203 	}
204 #else
205 	if (IS_ENABLED(CONFIG_SOC_SERIES_NRF53X) || IS_ENABLED(CONFIG_SOC_SERIES_NRF54HX)) {
206 		const uint32_t src_freq =
207 			(NRF_PDM_HAS_MCLKCONFIG && drv_cfg->clk_src == ACLK)
208 			/* The DMIC_NRFX_PDM_DEVICE() macro contains build
209 			 * assertions that make sure that the ACLK clock
210 			 * source is only used when it is available and only
211 			 * with the "hfclkaudio-frequency" property defined,
212 			 * but the default value of 0 here needs to be used
213 			 * to prevent compilation errors when the property is
214 			 * not defined (this expression will be eventually
215 			 * optimized away then).
216 			 */
217 			/* TODO : PS does not provide correct formula for nRF54H20 PDM_CLK.
218 			 * Assume that master clock source frequency is 8 MHz. Remove once
219 			 * correct formula is found.
220 			 */
221 			? DT_PROP_OR(DT_NODELABEL(clock), hfclkaudio_frequency,
222 				     0)
223 			: DMIC_NRFX_CLOCK_FREQ;
224 		uint32_t req_freq = req_rate * ratio;
225 		/* As specified in the nRF5340 PS:
226 		 *
227 		 * PDMCLKCTRL = 4096 * floor(f_pdm * 1048576 /
228 		 *                           (f_source + f_pdm / 2))
229 		 * f_actual = f_source / floor(1048576 * 4096 / PDMCLKCTRL)
230 		 */
231 		uint32_t clk_factor = (uint32_t)((req_freq * 1048576ULL) /
232 						 (src_freq + req_freq / 2));
233 		uint32_t act_freq = src_freq / (1048576 / clk_factor);
234 
235 		if (is_in_freq_range(act_freq, pdm_cfg) &&
236 		    is_better(act_freq, ratio, req_rate, best_diff, best_rate, best_freq)) {
237 			config->clock_freq = clk_factor * 4096;
238 
239 			better_found = true;
240 		}
241 	} else { /* -> !IS_ENABLED(CONFIG_SOC_SERIES_NRF53X)) */
242 		static const struct {
243 			uint32_t       freq_val;
244 			nrf_pdm_freq_t freq_enum;
245 		} freqs[] = {
246 			{ 1000000, NRF_PDM_FREQ_1000K },
247 			{ 1032000, NRF_PDM_FREQ_1032K },
248 			{ 1067000, NRF_PDM_FREQ_1067K },
249 #if defined(PDM_PDMCLKCTRL_FREQ_1231K)
250 			{ 1231000, NRF_PDM_FREQ_1231K },
251 #endif
252 #if defined(PDM_PDMCLKCTRL_FREQ_1280K)
253 			{ 1280000, NRF_PDM_FREQ_1280K },
254 #endif
255 #if defined(PDM_PDMCLKCTRL_FREQ_1333K)
256 			{ 1333000, NRF_PDM_FREQ_1333K }
257 #endif
258 		};
259 
260 		for (int i = 0; i < ARRAY_SIZE(freqs); ++i) {
261 			uint32_t freq_val = freqs[i].freq_val;
262 
263 			if (freq_val < pdm_cfg->io.min_pdm_clk_freq) {
264 				continue;
265 			}
266 			if (freq_val > pdm_cfg->io.max_pdm_clk_freq) {
267 				break;
268 			}
269 
270 			if (is_better(freq_val, ratio, req_rate,
271 				      best_diff, best_rate, best_freq)) {
272 				config->clock_freq = freqs[i].freq_enum;
273 
274 				/* Stop if an exact rate match is found. */
275 				if (*best_diff == 0) {
276 					return true;
277 				}
278 
279 				better_found = true;
280 			}
281 
282 			/* Since frequencies are in ascending order, stop
283 			 * checking next ones for the current ratio after
284 			 * resulting PCM rate goes above the one requested.
285 			 */
286 			if ((freq_val / ratio) > req_rate) {
287 				break;
288 			}
289 		}
290 	}
291 #endif /* NRF_PDM_HAS_PRESCALER */
292 
293 	return better_found;
294 }
295 
296 /* Finds clock settings that give the PCM output rate closest to that requested,
297  * taking into account the hardware limitations.
298  */
find_suitable_clock(const struct dmic_nrfx_pdm_drv_cfg * drv_cfg,nrfx_pdm_config_t * config,const struct dmic_cfg * pdm_cfg)299 static bool find_suitable_clock(const struct dmic_nrfx_pdm_drv_cfg *drv_cfg,
300 				nrfx_pdm_config_t *config,
301 				const struct dmic_cfg *pdm_cfg)
302 {
303 	uint32_t best_diff = UINT32_MAX;
304 	uint32_t best_rate;
305 	uint32_t best_freq;
306 
307 #if NRF_PDM_HAS_RATIO_CONFIG
308 	static const struct {
309 		uint8_t         ratio_val;
310 		nrf_pdm_ratio_t ratio_enum;
311 	} ratios[] = {
312 #if defined(PDM_RATIO_RATIO_Ratio32)
313 		{ 32, NRF_PDM_RATIO_32X },
314 #endif
315 #if defined(PDM_RATIO_RATIO_Ratio48)
316 		{ 48, NRF_PDM_RATIO_48X },
317 #endif
318 #if defined(PDM_RATIO_RATIO_Ratio50)
319 		{ 50, NRF_PDM_RATIO_50X },
320 #endif
321 		{ 64, NRF_PDM_RATIO_64X },
322 		{ 80, NRF_PDM_RATIO_80X },
323 #if defined(PDM_RATIO_RATIO_Ratio96)
324 		{ 96, NRF_PDM_RATIO_96X },
325 #endif
326 #if defined(PDM_RATIO_RATIO_Ratio100)
327 		{ 100, NRF_PDM_RATIO_100X },
328 #endif
329 #if defined(PDM_RATIO_RATIO_Ratio128)
330 		{ 128, NRF_PDM_RATIO_128X }
331 #endif
332 	};
333 
334 	for (int r = 0; best_diff != 0 && r < ARRAY_SIZE(ratios); ++r) {
335 		uint8_t ratio = ratios[r].ratio_val;
336 
337 		if (check_pdm_frequencies(drv_cfg, config, pdm_cfg, ratio,
338 					  &best_diff, &best_rate, &best_freq)) {
339 			config->ratio = ratios[r].ratio_enum;
340 
341 			/* Look no further if a configuration giving the exact
342 			 * PCM rate is found.
343 			 */
344 			if (best_diff == 0) {
345 				break;
346 			}
347 		}
348 	}
349 #else
350 	uint8_t ratio = 64;
351 
352 	(void)check_pdm_frequencies(drv_cfg, config, pdm_cfg, ratio,
353 				    &best_diff, &best_rate, &best_freq);
354 #endif
355 
356 	if (best_diff == UINT32_MAX) {
357 		return false;
358 	}
359 
360 	LOG_INF("PDM clock frequency: %u, actual PCM rate: %u",
361 		best_freq, best_rate);
362 	return true;
363 }
364 
dmic_nrfx_pdm_configure(const struct device * dev,struct dmic_cfg * config)365 static int dmic_nrfx_pdm_configure(const struct device *dev,
366 				   struct dmic_cfg *config)
367 {
368 	struct dmic_nrfx_pdm_drv_data *drv_data = dev->data;
369 	const struct dmic_nrfx_pdm_drv_cfg *drv_cfg = dev->config;
370 	struct pdm_chan_cfg *channel = &config->channel;
371 	struct pcm_stream_cfg *stream = &config->streams[0];
372 	uint32_t def_map, alt_map;
373 	nrfx_pdm_config_t nrfx_cfg;
374 	nrfx_err_t err;
375 
376 	if (drv_data->active) {
377 		LOG_ERR("Cannot configure device while it is active");
378 		return -EBUSY;
379 	}
380 
381 	/*
382 	 * This device supports only one stream and can be configured to return
383 	 * 16-bit samples for two channels (Left+Right samples) or one channel
384 	 * (only Left samples). Left and Right samples can be optionally swapped
385 	 * by changing the PDM_CLK edge on which the sampling is done
386 	 * Provide the valid channel maps for both the above configurations
387 	 * (to inform the requester what is available) and check if what is
388 	 * requested can be actually configured.
389 	 */
390 	if (channel->req_num_chan == 1) {
391 		def_map = dmic_build_channel_map(0, 0, PDM_CHAN_LEFT);
392 		alt_map = dmic_build_channel_map(0, 0, PDM_CHAN_RIGHT);
393 
394 		channel->act_num_chan = 1;
395 	} else {
396 		def_map = dmic_build_channel_map(0, 0, PDM_CHAN_LEFT)
397 			| dmic_build_channel_map(1, 0, PDM_CHAN_RIGHT);
398 		alt_map = dmic_build_channel_map(0, 0, PDM_CHAN_RIGHT)
399 			| dmic_build_channel_map(1, 0, PDM_CHAN_LEFT);
400 
401 		channel->act_num_chan = 2;
402 	}
403 
404 	channel->act_num_streams = 1;
405 	channel->act_chan_map_hi = 0;
406 	channel->act_chan_map_lo = def_map;
407 
408 	if (channel->req_num_streams != 1 ||
409 	    channel->req_num_chan > 2 ||
410 	    channel->req_num_chan < 1 ||
411 	    (channel->req_chan_map_lo != def_map &&
412 	     channel->req_chan_map_lo != alt_map) ||
413 	    channel->req_chan_map_hi != channel->act_chan_map_hi) {
414 		LOG_ERR("Requested configuration is not supported");
415 		return -EINVAL;
416 	}
417 
418 	/* If either rate or width is 0, the stream is to be disabled. */
419 	if (stream->pcm_rate == 0 || stream->pcm_width == 0) {
420 		if (drv_data->configured) {
421 			nrfx_pdm_uninit(drv_data->pdm);
422 			drv_data->configured = false;
423 		}
424 
425 		return 0;
426 	}
427 
428 	if (stream->pcm_width != 16) {
429 		LOG_ERR("Only 16-bit samples are supported");
430 		return -EINVAL;
431 	}
432 
433 	nrfx_cfg = drv_cfg->nrfx_def_cfg;
434 	nrfx_cfg.mode = channel->req_num_chan == 1
435 		      ? NRF_PDM_MODE_MONO
436 		      : NRF_PDM_MODE_STEREO;
437 	nrfx_cfg.edge = channel->req_chan_map_lo == def_map
438 		      ? NRF_PDM_EDGE_LEFTFALLING
439 		      : NRF_PDM_EDGE_LEFTRISING;
440 #if NRF_PDM_HAS_MCLKCONFIG
441 	nrfx_cfg.mclksrc = drv_cfg->clk_src == ACLK
442 			 ? NRF_PDM_MCLKSRC_ACLK
443 			 : NRF_PDM_MCLKSRC_PCLK32M;
444 #endif
445 	if (!find_suitable_clock(drv_cfg, &nrfx_cfg, config)) {
446 		LOG_ERR("Cannot find suitable PDM clock configuration.");
447 		return -EINVAL;
448 	}
449 
450 	if (drv_data->configured) {
451 		nrfx_pdm_uninit(drv_data->pdm);
452 		drv_data->configured = false;
453 	}
454 
455 	err = nrfx_pdm_init(drv_data->pdm, &nrfx_cfg, drv_cfg->event_handler);
456 	if (err != NRFX_SUCCESS) {
457 		LOG_ERR("Failed to initialize PDM: 0x%08x", err);
458 		return -EIO;
459 	}
460 
461 	drv_data->block_size = stream->block_size;
462 	drv_data->mem_slab   = stream->mem_slab;
463 
464 	/* Unless the PCLK32M source is used with the HFINT oscillator
465 	 * (which is always available without any additional actions),
466 	 * it is required to request the proper clock to be running
467 	 * before starting the transfer itself.
468 	 */
469 	drv_data->request_clock = (drv_cfg->clk_src != PCLK32M);
470 	drv_data->configured = true;
471 	return 0;
472 }
473 
start_transfer(struct dmic_nrfx_pdm_drv_data * drv_data)474 static int start_transfer(struct dmic_nrfx_pdm_drv_data *drv_data)
475 {
476 	nrfx_err_t err;
477 	int ret;
478 
479 	err = nrfx_pdm_start(drv_data->pdm);
480 	if (err == NRFX_SUCCESS) {
481 		return 0;
482 	}
483 
484 	LOG_ERR("Failed to start PDM: 0x%08x", err);
485 	ret =  -EIO;
486 
487 	if (drv_data->request_clock) {
488 		(void)onoff_release(drv_data->clk_mgr);
489 	}
490 
491 	drv_data->active = false;
492 	return ret;
493 }
494 
clock_started_callback(struct onoff_manager * mgr,struct onoff_client * cli,uint32_t state,int res)495 static void clock_started_callback(struct onoff_manager *mgr,
496 				   struct onoff_client *cli,
497 				   uint32_t state,
498 				   int res)
499 {
500 	struct dmic_nrfx_pdm_drv_data *drv_data =
501 		CONTAINER_OF(cli, struct dmic_nrfx_pdm_drv_data, clk_cli);
502 
503 	/* The driver can turn out to be inactive at this point if the STOP
504 	 * command was triggered before the clock has started. Do not start
505 	 * the actual transfer in such case.
506 	 */
507 	if (!drv_data->active) {
508 		(void)onoff_release(drv_data->clk_mgr);
509 	} else {
510 		(void)start_transfer(drv_data);
511 	}
512 }
513 
trigger_start(const struct device * dev)514 static int trigger_start(const struct device *dev)
515 {
516 	struct dmic_nrfx_pdm_drv_data *drv_data = dev->data;
517 	int ret;
518 
519 	drv_data->active = true;
520 
521 	/* If it is required to use certain HF clock, request it to be running
522 	 * first. If not, start the transfer directly.
523 	 */
524 	if (drv_data->request_clock) {
525 		sys_notify_init_callback(&drv_data->clk_cli.notify,
526 					 clock_started_callback);
527 		ret = onoff_request(drv_data->clk_mgr, &drv_data->clk_cli);
528 		if (ret < 0) {
529 			drv_data->active = false;
530 
531 			LOG_ERR("Failed to request clock: %d", ret);
532 			return -EIO;
533 		}
534 	} else {
535 		ret = start_transfer(drv_data);
536 		if (ret < 0) {
537 			return ret;
538 		}
539 	}
540 
541 	return 0;
542 }
543 
dmic_nrfx_pdm_trigger(const struct device * dev,enum dmic_trigger cmd)544 static int dmic_nrfx_pdm_trigger(const struct device *dev,
545 				 enum dmic_trigger cmd)
546 {
547 	struct dmic_nrfx_pdm_drv_data *drv_data = dev->data;
548 
549 	switch (cmd) {
550 	case DMIC_TRIGGER_PAUSE:
551 	case DMIC_TRIGGER_STOP:
552 		if (drv_data->active) {
553 			drv_data->stopping = true;
554 			nrfx_pdm_stop(drv_data->pdm);
555 		}
556 		break;
557 
558 	case DMIC_TRIGGER_RELEASE:
559 	case DMIC_TRIGGER_START:
560 		if (!drv_data->configured) {
561 			LOG_ERR("Device is not configured");
562 			return -EIO;
563 		} else if (!drv_data->active) {
564 			drv_data->stopping = false;
565 			return trigger_start(dev);
566 		}
567 		break;
568 
569 	default:
570 		LOG_ERR("Invalid command: %d", cmd);
571 		return -EINVAL;
572 	}
573 
574 	return 0;
575 }
576 
dmic_nrfx_pdm_read(const struct device * dev,uint8_t stream,void ** buffer,size_t * size,int32_t timeout)577 static int dmic_nrfx_pdm_read(const struct device *dev,
578 			      uint8_t stream,
579 			      void **buffer, size_t *size, int32_t timeout)
580 {
581 	struct dmic_nrfx_pdm_drv_data *drv_data = dev->data;
582 	int ret;
583 
584 	ARG_UNUSED(stream);
585 
586 	if (!drv_data->configured) {
587 		LOG_ERR("Device is not configured");
588 		return -EIO;
589 	}
590 
591 	ret = k_msgq_get(&drv_data->rx_queue, buffer, SYS_TIMEOUT_MS(timeout));
592 	if (ret != 0) {
593 		LOG_DBG("No audio data to be read");
594 	} else {
595 		LOG_DBG("Released buffer %p", *buffer);
596 
597 		*size = drv_data->block_size;
598 	}
599 
600 	return ret;
601 }
602 
603 #if CONFIG_CLOCK_CONTROL_NRF
init_clock_manager(const struct device * dev)604 static void init_clock_manager(const struct device *dev)
605 {
606 	struct dmic_nrfx_pdm_drv_data *drv_data = dev->data;
607 	clock_control_subsys_t subsys;
608 
609 #if NRF_CLOCK_HAS_HFCLKAUDIO
610 	const struct dmic_nrfx_pdm_drv_cfg *drv_cfg = dev->config;
611 
612 	if (drv_cfg->clk_src == ACLK) {
613 		subsys = CLOCK_CONTROL_NRF_SUBSYS_HFAUDIO;
614 	} else
615 #endif
616 	{
617 		subsys = CLOCK_CONTROL_NRF_SUBSYS_HF;
618 	}
619 
620 	drv_data->clk_mgr = z_nrf_clock_control_get_onoff(subsys);
621 	__ASSERT_NO_MSG(drv_data->clk_mgr != NULL);
622 }
623 #endif
624 
625 static const struct _dmic_ops dmic_ops = {
626 	.configure = dmic_nrfx_pdm_configure,
627 	.trigger = dmic_nrfx_pdm_trigger,
628 	.read = dmic_nrfx_pdm_read,
629 };
630 
631 #define PDM(idx) DT_NODELABEL(pdm##idx)
632 #define PDM_CLK_SRC(idx) DT_STRING_TOKEN(PDM(idx), clock_source)
633 
634 #define PDM_NRFX_DEVICE(idx)						     \
635 	static void *rx_msgs##idx[DT_PROP(PDM(idx), queue_size)];	     \
636 	static struct dmic_nrfx_pdm_drv_data dmic_nrfx_pdm_data##idx;	     \
637 	static const nrfx_pdm_t dmic_nrfx_pdm##idx = NRFX_PDM_INSTANCE(idx); \
638 	static int pdm_nrfx_init##idx(const struct device *dev)		     \
639 	{								     \
640 		IRQ_CONNECT(DT_IRQN(PDM(idx)), DT_IRQ(PDM(idx), priority),   \
641 			    nrfx_isr, nrfx_pdm_##idx##_irq_handler, 0);      \
642 		const struct dmic_nrfx_pdm_drv_cfg *drv_cfg = dev->config;   \
643 		int err = pinctrl_apply_state(drv_cfg->pcfg,		     \
644 					      PINCTRL_STATE_DEFAULT);	     \
645 		if (err < 0) {						     \
646 			return err;					     \
647 		}							     \
648 		dmic_nrfx_pdm_data##idx.pdm = &dmic_nrfx_pdm##idx;	     \
649 		k_msgq_init(&dmic_nrfx_pdm_data##idx.rx_queue,		     \
650 			    (char *)rx_msgs##idx, sizeof(void *),	     \
651 			    ARRAY_SIZE(rx_msgs##idx));			     \
652 		IF_ENABLED(CONFIG_CLOCK_CONTROL_NRF,			     \
653 			   (init_clock_manager(dev);))			     \
654 		return 0;						     \
655 	}								     \
656 	static void event_handler##idx(const nrfx_pdm_evt_t *evt)	     \
657 	{								     \
658 		event_handler(DEVICE_DT_GET(PDM(idx)), evt);		     \
659 	}								     \
660 	PINCTRL_DT_DEFINE(PDM(idx));					     \
661 	static const struct dmic_nrfx_pdm_drv_cfg dmic_nrfx_pdm_cfg##idx = { \
662 		.event_handler = event_handler##idx,			     \
663 		.nrfx_def_cfg =	NRFX_PDM_DEFAULT_CONFIG(0, 0),		     \
664 		.nrfx_def_cfg.skip_gpio_cfg = true,			     \
665 		.nrfx_def_cfg.skip_psel_cfg = true,			     \
666 		.pcfg = PINCTRL_DT_DEV_CONFIG_GET(PDM(idx)),		     \
667 		.clk_src = PDM_CLK_SRC(idx),				     \
668 		.mem_reg = DMM_DEV_TO_REG(PDM(idx)),			     \
669 	};								     \
670 	BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK || NRF_PDM_HAS_MCLKCONFIG,     \
671 		"Clock source ACLK is not available.");			     \
672 	BUILD_ASSERT(PDM_CLK_SRC(idx) != ACLK ||			     \
673 		     DT_NODE_HAS_PROP(DT_NODELABEL(clock),		     \
674 				      hfclkaudio_frequency),		     \
675 		"Clock source ACLK requires the hfclkaudio-frequency "	     \
676 		"property to be defined in the nordic,nrf-clock node.");     \
677 	DEVICE_DT_DEFINE(PDM(idx), pdm_nrfx_init##idx, NULL,		     \
678 			 &dmic_nrfx_pdm_data##idx, &dmic_nrfx_pdm_cfg##idx,  \
679 			 POST_KERNEL, CONFIG_AUDIO_DMIC_INIT_PRIORITY,	     \
680 			 &dmic_ops);
681 
682 #ifdef CONFIG_HAS_HW_NRF_PDM0
683 PDM_NRFX_DEVICE(0);
684 #endif
685 
686 #ifdef CONFIG_HAS_HW_NRF_PDM20
687 PDM_NRFX_DEVICE(20);
688 #endif
689 
690 #ifdef CONFIG_HAS_HW_NRF_PDM21
691 PDM_NRFX_DEVICE(21);
692 #endif
693