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