1 /*
2  * Copyright (c) 2019 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #define DT_DRV_COMPAT ti_tlv320dac
8 
9 #include <errno.h>
10 
11 #include <zephyr/sys/util.h>
12 
13 #include <zephyr/device.h>
14 #include <zephyr/drivers/i2c.h>
15 #include <zephyr/drivers/gpio.h>
16 #include <zephyr/sys/util.h>
17 #include <zephyr/audio/codec.h>
18 #include "tlv320dac310x.h"
19 
20 #define LOG_LEVEL CONFIG_AUDIO_CODEC_LOG_LEVEL
21 #include <zephyr/logging/log.h>
22 LOG_MODULE_REGISTER(tlv320dac310x);
23 
24 #define CODEC_OUTPUT_VOLUME_MAX		0
25 #define CODEC_OUTPUT_VOLUME_MIN		(-78 * 2)
26 
27 struct codec_driver_config {
28 	struct i2c_dt_spec bus;
29 	struct gpio_dt_spec reset_gpio;
30 };
31 
32 struct codec_driver_data {
33 	struct reg_addr	reg_addr_cache;
34 };
35 
36 static struct codec_driver_config codec_device_config = {
37 	.bus		= I2C_DT_SPEC_INST_GET(0),
38 	.reset_gpio	= GPIO_DT_SPEC_INST_GET(0, reset_gpios),
39 };
40 
41 static struct codec_driver_data codec_device_data;
42 
43 static void codec_write_reg(const struct device *dev, struct reg_addr reg,
44 			    uint8_t val);
45 static void codec_read_reg(const struct device *dev, struct reg_addr reg,
46 			   uint8_t *val);
47 static void codec_soft_reset(const struct device *dev);
48 static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg);
49 static int codec_configure_clocks(const struct device *dev,
50 				  struct audio_codec_cfg *cfg);
51 static int codec_configure_filters(const struct device *dev,
52 				   audio_dai_cfg_t *cfg);
53 static enum osr_multiple codec_get_osr_multiple(audio_dai_cfg_t *cfg);
54 static void codec_configure_output(const struct device *dev);
55 static int codec_set_output_volume(const struct device *dev, int vol);
56 
57 #if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
58 static void codec_read_all_regs(const struct device *dev);
59 #define CODEC_DUMP_REGS(dev)	codec_read_all_regs((dev))
60 #else
61 #define CODEC_DUMP_REGS(dev)
62 #endif
63 
codec_initialize(const struct device * dev)64 static int codec_initialize(const struct device *dev)
65 {
66 	const struct codec_driver_config *const dev_cfg = dev->config;
67 
68 	if (!device_is_ready(dev_cfg->bus.bus)) {
69 		LOG_ERR("I2C device not ready");
70 		return -ENODEV;
71 	}
72 
73 	if (!gpio_is_ready_dt(&dev_cfg->reset_gpio)) {
74 		LOG_ERR("GPIO device not ready");
75 		return -ENODEV;
76 	}
77 
78 	return 0;
79 }
80 
codec_configure(const struct device * dev,struct audio_codec_cfg * cfg)81 static int codec_configure(const struct device *dev,
82 			   struct audio_codec_cfg *cfg)
83 {
84 	const struct codec_driver_config *const dev_cfg = dev->config;
85 	int ret;
86 
87 	if (cfg->dai_type != AUDIO_DAI_TYPE_I2S) {
88 		LOG_ERR("dai_type must be AUDIO_DAI_TYPE_I2S");
89 		return -EINVAL;
90 	}
91 
92 	/* Configure reset GPIO, and set the line to inactive, which will also
93 	 * de-assert the reset line and thus enable the codec.
94 	 */
95 	gpio_pin_configure_dt(&dev_cfg->reset_gpio, GPIO_OUTPUT_INACTIVE);
96 
97 	codec_soft_reset(dev);
98 
99 	ret = codec_configure_clocks(dev, cfg);
100 	if (ret == 0) {
101 		ret = codec_configure_dai(dev, &cfg->dai_cfg);
102 	}
103 	if (ret == 0) {
104 		ret = codec_configure_filters(dev, &cfg->dai_cfg);
105 	}
106 	codec_configure_output(dev);
107 
108 	return ret;
109 }
110 
codec_start_output(const struct device * dev)111 static void codec_start_output(const struct device *dev)
112 {
113 	/* powerup DAC channels */
114 	codec_write_reg(dev, DATA_PATH_SETUP_ADDR, DAC_LR_POWERUP_DEFAULT);
115 
116 	/* unmute DAC channels */
117 	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_UNMUTE_DEFAULT);
118 
119 	CODEC_DUMP_REGS(dev);
120 }
121 
codec_stop_output(const struct device * dev)122 static void codec_stop_output(const struct device *dev)
123 {
124 	/* mute DAC channels */
125 	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_MUTE_DEFAULT);
126 
127 	/* powerdown DAC channels */
128 	codec_write_reg(dev, DATA_PATH_SETUP_ADDR, DAC_LR_POWERDN_DEFAULT);
129 }
130 
codec_mute_output(const struct device * dev)131 static void codec_mute_output(const struct device *dev)
132 {
133 	/* mute DAC channels */
134 	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_MUTE_DEFAULT);
135 }
136 
codec_unmute_output(const struct device * dev)137 static void codec_unmute_output(const struct device *dev)
138 {
139 	/* unmute DAC channels */
140 	codec_write_reg(dev, VOL_CTRL_ADDR, VOL_CTRL_UNMUTE_DEFAULT);
141 }
142 
codec_set_property(const struct device * dev,audio_property_t property,audio_channel_t channel,audio_property_value_t val)143 static int codec_set_property(const struct device *dev,
144 			      audio_property_t property,
145 			      audio_channel_t channel,
146 			      audio_property_value_t val)
147 {
148 	/* individual channel control not currently supported */
149 	if (channel != AUDIO_CHANNEL_ALL) {
150 		LOG_ERR("channel %u invalid. must be AUDIO_CHANNEL_ALL",
151 			channel);
152 		return -EINVAL;
153 	}
154 
155 	switch (property) {
156 	case AUDIO_PROPERTY_OUTPUT_VOLUME:
157 		return codec_set_output_volume(dev, val.vol);
158 
159 	case AUDIO_PROPERTY_OUTPUT_MUTE:
160 		if (val.mute) {
161 			codec_mute_output(dev);
162 		} else {
163 			codec_unmute_output(dev);
164 		}
165 		return 0;
166 
167 	default:
168 		break;
169 	}
170 
171 	return -EINVAL;
172 }
173 
codec_apply_properties(const struct device * dev)174 static int codec_apply_properties(const struct device *dev)
175 {
176 	/* nothing to do because there is nothing cached */
177 	return 0;
178 }
179 
codec_write_reg(const struct device * dev,struct reg_addr reg,uint8_t val)180 static void codec_write_reg(const struct device *dev, struct reg_addr reg,
181 			    uint8_t val)
182 {
183 	struct codec_driver_data *const dev_data = dev->data;
184 	const struct codec_driver_config *const dev_cfg = dev->config;
185 
186 	/* set page if different */
187 	if (dev_data->reg_addr_cache.page != reg.page) {
188 		i2c_reg_write_byte_dt(&dev_cfg->bus, 0, reg.page);
189 		dev_data->reg_addr_cache.page = reg.page;
190 	}
191 
192 	i2c_reg_write_byte_dt(&dev_cfg->bus, reg.reg_addr, val);
193 	LOG_DBG("WR PG:%u REG:%02u VAL:0x%02x",
194 			reg.page, reg.reg_addr, val);
195 }
196 
codec_read_reg(const struct device * dev,struct reg_addr reg,uint8_t * val)197 static void codec_read_reg(const struct device *dev, struct reg_addr reg,
198 			   uint8_t *val)
199 {
200 	struct codec_driver_data *const dev_data = dev->data;
201 	const struct codec_driver_config *const dev_cfg = dev->config;
202 
203 	/* set page if different */
204 	if (dev_data->reg_addr_cache.page != reg.page) {
205 		i2c_reg_write_byte_dt(&dev_cfg->bus, 0, reg.page);
206 		dev_data->reg_addr_cache.page = reg.page;
207 	}
208 
209 	i2c_reg_read_byte_dt(&dev_cfg->bus, reg.reg_addr, val);
210 	LOG_DBG("RD PG:%u REG:%02u VAL:0x%02x",
211 			reg.page, reg.reg_addr, *val);
212 }
213 
codec_soft_reset(const struct device * dev)214 static void codec_soft_reset(const struct device *dev)
215 {
216 	/* soft reset the DAC */
217 	codec_write_reg(dev, SOFT_RESET_ADDR, SOFT_RESET_ASSERT);
218 }
219 
codec_configure_dai(const struct device * dev,audio_dai_cfg_t * cfg)220 static int codec_configure_dai(const struct device *dev, audio_dai_cfg_t *cfg)
221 {
222 	uint8_t val;
223 
224 	/* configure I2S interface */
225 	val = IF_CTRL_IFTYPE(IF_CTRL_IFTYPE_I2S);
226 	if (cfg->i2s.options & I2S_OPT_BIT_CLK_MASTER) {
227 		val |= IF_CTRL_BCLK_OUT;
228 	}
229 
230 	if (cfg->i2s.options & I2S_OPT_FRAME_CLK_MASTER) {
231 		val |= IF_CTRL_WCLK_OUT;
232 	}
233 
234 	switch (cfg->i2s.word_size) {
235 	case AUDIO_PCM_WIDTH_16_BITS:
236 		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_16);
237 		break;
238 	case AUDIO_PCM_WIDTH_20_BITS:
239 		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_20);
240 		break;
241 	case AUDIO_PCM_WIDTH_24_BITS:
242 		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_24);
243 		break;
244 	case AUDIO_PCM_WIDTH_32_BITS:
245 		val |= IF_CTRL_WLEN(IF_CTRL_WLEN_32);
246 		break;
247 	default:
248 		LOG_ERR("Unsupported PCM sample bit width %u",
249 				cfg->i2s.word_size);
250 		return -EINVAL;
251 	}
252 
253 	codec_write_reg(dev, IF_CTRL1_ADDR, val);
254 	return 0;
255 }
256 
codec_configure_clocks(const struct device * dev,struct audio_codec_cfg * cfg)257 static int codec_configure_clocks(const struct device *dev,
258 				  struct audio_codec_cfg *cfg)
259 {
260 	int dac_clk, mod_clk;
261 	struct i2s_config *i2s;
262 	int osr, osr_min, osr_max;
263 	enum osr_multiple osr_multiple;
264 	int mdac, ndac, bclk_div, mclk_div;
265 
266 	i2s = &cfg->dai_cfg.i2s;
267 	LOG_DBG("MCLK %u Hz PCM Rate: %u Hz", cfg->mclk_freq,
268 			i2s->frame_clk_freq);
269 
270 	if (cfg->mclk_freq <= DAC_PROC_CLK_FREQ_MAX) {
271 		/* use MCLK frequency as the DAC processing clock */
272 		ndac = 1;
273 	} else {
274 		ndac = cfg->mclk_freq / DAC_PROC_CLK_FREQ_MAX;
275 	}
276 
277 	dac_clk = cfg->mclk_freq / ndac;
278 
279 	/* determine OSR Multiple based on PCM rate */
280 	osr_multiple = codec_get_osr_multiple(&cfg->dai_cfg);
281 
282 	/*
283 	 * calculate MOD clock such that it is an integer multiple of
284 	 * cfg->i2s.frame_clk_freq and
285 	 * DAC_MOD_CLK_FREQ_MIN <= MOD clock <= DAC_MOD_CLK_FREQ_MAX
286 	 */
287 	osr_min = (DAC_MOD_CLK_FREQ_MIN + i2s->frame_clk_freq - 1) /
288 		i2s->frame_clk_freq;
289 	osr_max = DAC_MOD_CLK_FREQ_MAX / i2s->frame_clk_freq;
290 
291 	/* round mix and max values to the required multiple */
292 	osr_max = (osr_max / osr_multiple) * osr_multiple;
293 	osr_min = DIV_ROUND_UP(osr_min, osr_multiple);
294 
295 	osr = osr_max;
296 	while (osr >= osr_min) {
297 		mod_clk = i2s->frame_clk_freq * osr;
298 
299 		/* calculate mdac */
300 		mdac = dac_clk / mod_clk;
301 
302 		/* check if mdac is an integer */
303 		if ((mdac * mod_clk) == dac_clk) {
304 			/* found suitable dividers */
305 			break;
306 		}
307 		osr -= osr_multiple;
308 	}
309 
310 	/* check if suitable value was found */
311 	if (osr < osr_min) {
312 		LOG_ERR("Unable to find suitable mdac and osr values");
313 		return -EINVAL;
314 	}
315 
316 	LOG_DBG("Processing freq: %u Hz Modulator freq: %u Hz",
317 			dac_clk, mod_clk);
318 	LOG_DBG("NDAC: %u MDAC: %u OSR: %u", ndac, mdac, osr);
319 
320 	if (i2s->options & I2S_OPT_BIT_CLK_MASTER) {
321 		bclk_div = osr * mdac / (i2s->word_size * 2U); /* stereo */
322 		if ((bclk_div * i2s->word_size * 2) != (osr * mdac)) {
323 			LOG_ERR("Unable to generate BCLK %u from MCLK %u",
324 				i2s->frame_clk_freq * i2s->word_size * 2U,
325 				cfg->mclk_freq);
326 			return -EINVAL;
327 		}
328 		LOG_DBG("I2S Master BCLKDIV: %u", bclk_div);
329 		codec_write_reg(dev, BCLK_DIV_ADDR,
330 				BCLK_DIV_POWER_UP | BCLK_DIV(bclk_div));
331 	}
332 
333 	/* set NDAC, then MDAC, followed by OSR */
334 	codec_write_reg(dev, NDAC_DIV_ADDR,
335 			(uint8_t)(NDAC_DIV(ndac) | NDAC_POWER_UP_MASK));
336 	codec_write_reg(dev, MDAC_DIV_ADDR,
337 			(uint8_t)(MDAC_DIV(mdac) | MDAC_POWER_UP_MASK));
338 	codec_write_reg(dev, OSR_MSB_ADDR, (uint8_t)((osr >> 8) & OSR_MSB_MASK));
339 	codec_write_reg(dev, OSR_LSB_ADDR, (uint8_t)(osr & OSR_LSB_MASK));
340 
341 	if (i2s->options & I2S_OPT_BIT_CLK_MASTER) {
342 		codec_write_reg(dev, BCLK_DIV_ADDR,
343 				BCLK_DIV(bclk_div) | BCLK_DIV_POWER_UP);
344 	}
345 
346 	/* calculate MCLK divider to get ~1MHz */
347 	mclk_div = DIV_ROUND_UP(cfg->mclk_freq, 1000000);
348 	/* setup timer clock to be MCLK divided */
349 	codec_write_reg(dev, TIMER_MCLK_DIV_ADDR,
350 			TIMER_MCLK_DIV_EN_EXT | TIMER_MCLK_DIV_VAL(mclk_div));
351 	LOG_DBG("Timer MCLK Divider: %u", mclk_div);
352 
353 	return 0;
354 }
355 
codec_configure_filters(const struct device * dev,audio_dai_cfg_t * cfg)356 static int codec_configure_filters(const struct device *dev,
357 				   audio_dai_cfg_t *cfg)
358 {
359 	enum proc_block proc_blk;
360 
361 	/* determine decimation filter type */
362 	if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_192K) {
363 		proc_blk = PRB_P18_DECIMATION_C;
364 		LOG_INF("PCM Rate: %u Filter C PRB P18 selected",
365 				cfg->i2s.frame_clk_freq);
366 	} else if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_96K) {
367 		proc_blk = PRB_P10_DECIMATION_B;
368 		LOG_INF("PCM Rate: %u Filter B PRB P10 selected",
369 				cfg->i2s.frame_clk_freq);
370 	} else {
371 		proc_blk = PRB_P25_DECIMATION_A;
372 		LOG_INF("PCM Rate: %u Filter A PRB P25 selected",
373 				cfg->i2s.frame_clk_freq);
374 	}
375 
376 	codec_write_reg(dev, PROC_BLK_SEL_ADDR, PROC_BLK_SEL(proc_blk));
377 	return 0;
378 }
379 
codec_get_osr_multiple(audio_dai_cfg_t * cfg)380 static enum osr_multiple codec_get_osr_multiple(audio_dai_cfg_t *cfg)
381 {
382 	enum osr_multiple osr;
383 
384 	if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_192K) {
385 		osr = OSR_MULTIPLE_2;
386 	} else if (cfg->i2s.frame_clk_freq >= AUDIO_PCM_RATE_96K) {
387 		osr = OSR_MULTIPLE_4;
388 	} else {
389 		osr = OSR_MULTIPLE_8;
390 	}
391 
392 	LOG_INF("PCM Rate: %u OSR Multiple: %u", cfg->i2s.frame_clk_freq,
393 			osr);
394 	return osr;
395 }
396 
codec_configure_output(const struct device * dev)397 static void codec_configure_output(const struct device *dev)
398 {
399 	uint8_t val;
400 
401 	/*
402 	 * set common mode voltage to 1.65V (half of AVDD)
403 	 * AVDD is typically 3.3V
404 	 */
405 	codec_read_reg(dev, HEADPHONE_DRV_ADDR, &val);
406 	val &= ~HEADPHONE_DRV_CM_MASK;
407 	val |= HEADPHONE_DRV_CM(CM_VOLTAGE_1P65) | HEADPHONE_DRV_RESERVED;
408 	codec_write_reg(dev, HEADPHONE_DRV_ADDR, val);
409 
410 	/* enable pop removal on power down/up */
411 	codec_read_reg(dev, HP_OUT_POP_RM_ADDR, &val);
412 	codec_write_reg(dev, HP_OUT_POP_RM_ADDR, val | HP_OUT_POP_RM_ENABLE);
413 
414 	/* route DAC output to Headphone */
415 	val = OUTPUT_ROUTING_HPL | OUTPUT_ROUTING_HPR;
416 	codec_write_reg(dev, OUTPUT_ROUTING_ADDR, val);
417 
418 	/* enable volume control on Headphone out */
419 	codec_write_reg(dev, HPL_ANA_VOL_CTRL_ADDR,
420 			HPX_ANA_VOL(HPX_ANA_VOL_DEFAULT));
421 	codec_write_reg(dev, HPR_ANA_VOL_CTRL_ADDR,
422 			HPX_ANA_VOL(HPX_ANA_VOL_DEFAULT));
423 
424 	/* set headphone outputs as line-out */
425 	codec_write_reg(dev, HEADPHONE_DRV_CTRL_ADDR, HEADPHONE_DRV_LINEOUT);
426 
427 	/* unmute headphone drivers */
428 	codec_write_reg(dev, HPL_DRV_GAIN_CTRL_ADDR, HPX_DRV_UNMUTE);
429 	codec_write_reg(dev, HPR_DRV_GAIN_CTRL_ADDR, HPX_DRV_UNMUTE);
430 
431 	/* power up headphone drivers */
432 	codec_read_reg(dev, HEADPHONE_DRV_ADDR, &val);
433 	val |= HEADPHONE_DRV_POWERUP | HEADPHONE_DRV_RESERVED;
434 	codec_write_reg(dev, HEADPHONE_DRV_ADDR, val);
435 }
436 
codec_set_output_volume(const struct device * dev,int vol)437 static int codec_set_output_volume(const struct device *dev, int vol)
438 {
439 	uint8_t vol_val;
440 	int vol_index;
441 	uint8_t vol_array[] = {
442 		107, 108, 110, 113, 116, 120, 125, 128, 132, 138, 144
443 	};
444 
445 	if ((vol > CODEC_OUTPUT_VOLUME_MAX) ||
446 			(vol < CODEC_OUTPUT_VOLUME_MIN)) {
447 		LOG_ERR("Invalid volume %d.%d dB",
448 				vol >> 1, ((uint32_t)vol & 1) ? 5 : 0);
449 		return -EINVAL;
450 	}
451 
452 	/* remove sign */
453 	vol = -vol;
454 
455 	/* if volume is near floor, set minimum */
456 	if (vol > HPX_ANA_VOL_FLOOR) {
457 		vol_val = HPX_ANA_VOL_FLOOR;
458 	} else if (vol > HPX_ANA_VOL_LOW_THRESH) {
459 		/* lookup low volume values */
460 		for (vol_index = 0; vol_index < ARRAY_SIZE(vol_array); vol_index++) {
461 			if (vol_array[vol_index] >= vol) {
462 				break;
463 			}
464 		}
465 		vol_val = HPX_ANA_VOL_LOW_THRESH + vol_index + 1;
466 	} else {
467 		vol_val = (uint8_t)vol;
468 	}
469 
470 	codec_write_reg(dev, HPL_ANA_VOL_CTRL_ADDR, HPX_ANA_VOL(vol_val));
471 	codec_write_reg(dev, HPR_ANA_VOL_CTRL_ADDR, HPX_ANA_VOL(vol_val));
472 	return 0;
473 }
474 
475 #if (LOG_LEVEL >= LOG_LEVEL_DEBUG)
codec_read_all_regs(const struct device * dev)476 static void codec_read_all_regs(const struct device *dev)
477 {
478 	uint8_t val;
479 
480 	codec_read_reg(dev, SOFT_RESET_ADDR, &val);
481 	codec_read_reg(dev, NDAC_DIV_ADDR, &val);
482 	codec_read_reg(dev, MDAC_DIV_ADDR, &val);
483 	codec_read_reg(dev, OSR_MSB_ADDR, &val);
484 	codec_read_reg(dev, OSR_LSB_ADDR, &val);
485 	codec_read_reg(dev, IF_CTRL1_ADDR, &val);
486 	codec_read_reg(dev, BCLK_DIV_ADDR, &val);
487 	codec_read_reg(dev, OVF_FLAG_ADDR, &val);
488 	codec_read_reg(dev, PROC_BLK_SEL_ADDR, &val);
489 	codec_read_reg(dev, DATA_PATH_SETUP_ADDR, &val);
490 	codec_read_reg(dev, VOL_CTRL_ADDR, &val);
491 	codec_read_reg(dev, L_DIG_VOL_CTRL_ADDR, &val);
492 	codec_read_reg(dev, DRC_CTRL1_ADDR, &val);
493 	codec_read_reg(dev, L_BEEP_GEN_ADDR, &val);
494 	codec_read_reg(dev, R_BEEP_GEN_ADDR, &val);
495 	codec_read_reg(dev, BEEP_LEN_MSB_ADDR, &val);
496 	codec_read_reg(dev, BEEP_LEN_MIB_ADDR, &val);
497 	codec_read_reg(dev, BEEP_LEN_LSB_ADDR, &val);
498 
499 	codec_read_reg(dev, HEADPHONE_DRV_ADDR, &val);
500 	codec_read_reg(dev, HP_OUT_POP_RM_ADDR, &val);
501 	codec_read_reg(dev, OUTPUT_ROUTING_ADDR, &val);
502 	codec_read_reg(dev, HPL_ANA_VOL_CTRL_ADDR, &val);
503 	codec_read_reg(dev, HPR_ANA_VOL_CTRL_ADDR, &val);
504 	codec_read_reg(dev, HPL_DRV_GAIN_CTRL_ADDR, &val);
505 	codec_read_reg(dev, HPR_DRV_GAIN_CTRL_ADDR, &val);
506 	codec_read_reg(dev, HEADPHONE_DRV_CTRL_ADDR, &val);
507 
508 	codec_read_reg(dev, TIMER_MCLK_DIV_ADDR, &val);
509 }
510 #endif
511 
512 static const struct audio_codec_api codec_driver_api = {
513 	.configure		= codec_configure,
514 	.start_output		= codec_start_output,
515 	.stop_output		= codec_stop_output,
516 	.set_property		= codec_set_property,
517 	.apply_properties	= codec_apply_properties,
518 };
519 
520 DEVICE_DT_INST_DEFINE(0, codec_initialize, NULL, &codec_device_data,
521 		&codec_device_config, POST_KERNEL,
522 		CONFIG_AUDIO_CODEC_INIT_PRIORITY, &codec_driver_api);
523