xref: /openbmc/linux/sound/pci/oxygen/xonar_dg.c (revision 66410bfdf14f7c2ad3b2d4a8adeab41d368b6f05)
1 /*
2  * card driver for the Xonar DG
3  *
4  * Copyright (c) Clemens Ladisch <clemens@ladisch.de>
5  *
6  *
7  *  This driver is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License, version 2.
9  *
10  *  This driver is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this driver; if not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 /*
20  * Xonar DG
21  * --------
22  *
23  * CMI8788:
24  *
25  *   SPI 0 -> CS4245
26  *
27  *   GPIO 3 <- ?
28  *   GPIO 4 <- headphone detect
29  *   GPIO 5 -> route input jack to line-in (0) or mic-in (1)
30  *   GPIO 6 -> route input jack to line-in (0) or mic-in (1)
31  *   GPIO 7 -> enable rear headphone amp
32  *   GPIO 8 -> enable output to speakers
33  *
34  * CS4245:
35  *
36  *   input 1 <- aux
37  *   input 2 <- front mic
38  *   input 4 <- line/mic
39  *   aux out -> front panel headphones
40  */
41 
42 #include <linux/pci.h>
43 #include <sound/control.h>
44 #include <sound/core.h>
45 #include <sound/info.h>
46 #include <sound/pcm.h>
47 #include <sound/tlv.h>
48 #include "oxygen.h"
49 #include "xonar_dg.h"
50 #include "cs4245.h"
51 
52 #define GPIO_MAGIC		0x0008
53 #define GPIO_HP_DETECT		0x0010
54 #define GPIO_INPUT_ROUTE	0x0060
55 #define GPIO_HP_REAR		0x0080
56 #define GPIO_OUTPUT_ENABLE	0x0100
57 
58 struct dg {
59 	unsigned int output_sel;
60 	s8 input_vol[4][2];
61 	unsigned int input_sel;
62 	u8 hp_vol_att;
63 	u8 cs4245_regs[0x11];
64 };
65 
66 static void cs4245_write(struct oxygen *chip, unsigned int reg, u8 value)
67 {
68 	struct dg *data = chip->model_data;
69 
70 	oxygen_write_spi(chip, OXYGEN_SPI_TRIGGER |
71 			 OXYGEN_SPI_DATA_LENGTH_3 |
72 			 OXYGEN_SPI_CLOCK_1280 |
73 			 (0 << OXYGEN_SPI_CODEC_SHIFT) |
74 			 OXYGEN_SPI_CEN_LATCH_CLOCK_HI,
75 			 CS4245_SPI_ADDRESS |
76 			 CS4245_SPI_WRITE |
77 			 (value << 8) | reg);
78 	data->cs4245_regs[reg] = value;
79 }
80 
81 static void cs4245_write_cached(struct oxygen *chip, unsigned int reg, u8 value)
82 {
83 	struct dg *data = chip->model_data;
84 
85 	if (value != data->cs4245_regs[reg])
86 		cs4245_write(chip, reg, value);
87 }
88 
89 static void cs4245_registers_init(struct oxygen *chip)
90 {
91 	struct dg *data = chip->model_data;
92 
93 	cs4245_write(chip, CS4245_POWER_CTRL, CS4245_PDN);
94 	cs4245_write(chip, CS4245_DAC_CTRL_1,
95 		     data->cs4245_regs[CS4245_DAC_CTRL_1]);
96 	cs4245_write(chip, CS4245_ADC_CTRL,
97 		     data->cs4245_regs[CS4245_ADC_CTRL]);
98 	cs4245_write(chip, CS4245_SIGNAL_SEL,
99 		     data->cs4245_regs[CS4245_SIGNAL_SEL]);
100 	cs4245_write(chip, CS4245_PGA_B_CTRL,
101 		     data->cs4245_regs[CS4245_PGA_B_CTRL]);
102 	cs4245_write(chip, CS4245_PGA_A_CTRL,
103 		     data->cs4245_regs[CS4245_PGA_A_CTRL]);
104 	cs4245_write(chip, CS4245_ANALOG_IN,
105 		     data->cs4245_regs[CS4245_ANALOG_IN]);
106 	cs4245_write(chip, CS4245_DAC_A_CTRL,
107 		     data->cs4245_regs[CS4245_DAC_A_CTRL]);
108 	cs4245_write(chip, CS4245_DAC_B_CTRL,
109 		     data->cs4245_regs[CS4245_DAC_B_CTRL]);
110 	cs4245_write(chip, CS4245_DAC_CTRL_2,
111 		     CS4245_DAC_SOFT | CS4245_DAC_ZERO | CS4245_INVERT_DAC);
112 	cs4245_write(chip, CS4245_INT_MASK, 0);
113 	cs4245_write(chip, CS4245_POWER_CTRL, 0);
114 }
115 
116 static void cs4245_init(struct oxygen *chip)
117 {
118 	struct dg *data = chip->model_data;
119 
120 	data->cs4245_regs[CS4245_DAC_CTRL_1] =
121 		CS4245_DAC_FM_SINGLE | CS4245_DAC_DIF_LJUST;
122 	data->cs4245_regs[CS4245_ADC_CTRL] =
123 		CS4245_ADC_FM_SINGLE | CS4245_ADC_DIF_LJUST;
124 	data->cs4245_regs[CS4245_SIGNAL_SEL] =
125 		CS4245_A_OUT_SEL_HIZ | CS4245_ASYNCH;
126 	data->cs4245_regs[CS4245_PGA_B_CTRL] = 0;
127 	data->cs4245_regs[CS4245_PGA_A_CTRL] = 0;
128 	data->cs4245_regs[CS4245_ANALOG_IN] =
129 		CS4245_PGA_SOFT | CS4245_PGA_ZERO | CS4245_SEL_INPUT_4;
130 	data->cs4245_regs[CS4245_DAC_A_CTRL] = 0;
131 	data->cs4245_regs[CS4245_DAC_B_CTRL] = 0;
132 	cs4245_registers_init(chip);
133 	snd_component_add(chip->card, "CS4245");
134 }
135 
136 static void dg_output_enable(struct oxygen *chip)
137 {
138 	msleep(2500);
139 	oxygen_set_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
140 }
141 
142 static void dg_init(struct oxygen *chip)
143 {
144 	struct dg *data = chip->model_data;
145 
146 	data->output_sel = 0;
147 	data->input_sel = 3;
148 	data->hp_vol_att = 2 * 16;
149 
150 	cs4245_init(chip);
151 
152 	oxygen_clear_bits16(chip, OXYGEN_GPIO_CONTROL,
153 			    GPIO_MAGIC | GPIO_HP_DETECT);
154 	oxygen_set_bits16(chip, OXYGEN_GPIO_CONTROL,
155 			  GPIO_INPUT_ROUTE | GPIO_HP_REAR | GPIO_OUTPUT_ENABLE);
156 	oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA,
157 			    GPIO_INPUT_ROUTE | GPIO_HP_REAR);
158 	dg_output_enable(chip);
159 }
160 
161 static void dg_cleanup(struct oxygen *chip)
162 {
163 	oxygen_clear_bits16(chip, OXYGEN_GPIO_DATA, GPIO_OUTPUT_ENABLE);
164 }
165 
166 static void dg_suspend(struct oxygen *chip)
167 {
168 	dg_cleanup(chip);
169 }
170 
171 static void dg_resume(struct oxygen *chip)
172 {
173 	cs4245_registers_init(chip);
174 	dg_output_enable(chip);
175 }
176 
177 static void set_cs4245_dac_params(struct oxygen *chip,
178 				  struct snd_pcm_hw_params *params)
179 {
180 	struct dg *data = chip->model_data;
181 	u8 value;
182 
183 	value = data->cs4245_regs[CS4245_DAC_CTRL_1] & ~CS4245_DAC_FM_MASK;
184 	if (params_rate(params) <= 50000)
185 		value |= CS4245_DAC_FM_SINGLE;
186 	else if (params_rate(params) <= 100000)
187 		value |= CS4245_DAC_FM_DOUBLE;
188 	else
189 		value |= CS4245_DAC_FM_QUAD;
190 	cs4245_write_cached(chip, CS4245_DAC_CTRL_1, value);
191 }
192 
193 static void set_cs4245_adc_params(struct oxygen *chip,
194 				  struct snd_pcm_hw_params *params)
195 {
196 	struct dg *data = chip->model_data;
197 	u8 value;
198 
199 	value = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_ADC_FM_MASK;
200 	if (params_rate(params) <= 50000)
201 		value |= CS4245_ADC_FM_SINGLE;
202 	else if (params_rate(params) <= 100000)
203 		value |= CS4245_ADC_FM_DOUBLE;
204 	else
205 		value |= CS4245_ADC_FM_QUAD;
206 	cs4245_write_cached(chip, CS4245_ADC_CTRL, value);
207 }
208 
209 static int output_switch_info(struct snd_kcontrol *ctl,
210 			      struct snd_ctl_elem_info *info)
211 {
212 	static const char *const names[3] = {
213 		"Speakers", "Headphones", "FP Headphones"
214 	};
215 
216 	info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
217 	info->count = 1;
218 	info->value.enumerated.items = 3;
219 	if (info->value.enumerated.item >= 3)
220 		info->value.enumerated.item = 2;
221 	strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
222 	return 0;
223 }
224 
225 static int output_switch_get(struct snd_kcontrol *ctl,
226 			     struct snd_ctl_elem_value *value)
227 {
228 	struct oxygen *chip = ctl->private_data;
229 	struct dg *data = chip->model_data;
230 
231 	mutex_lock(&chip->mutex);
232 	value->value.enumerated.item[0] = data->output_sel;
233 	mutex_unlock(&chip->mutex);
234 	return 0;
235 }
236 
237 static int output_switch_put(struct snd_kcontrol *ctl,
238 			     struct snd_ctl_elem_value *value)
239 {
240 	struct oxygen *chip = ctl->private_data;
241 	struct dg *data = chip->model_data;
242 	u8 reg;
243 	int changed;
244 
245 	if (value->value.enumerated.item[0] > 2)
246 		return -EINVAL;
247 
248 	mutex_lock(&chip->mutex);
249 	changed = value->value.enumerated.item[0] != data->output_sel;
250 	if (changed) {
251 		data->output_sel = value->value.enumerated.item[0];
252 
253 		reg = data->cs4245_regs[CS4245_SIGNAL_SEL] &
254 						~CS4245_A_OUT_SEL_MASK;
255 		reg |= data->output_sel == 2 ?
256 				CS4245_A_OUT_SEL_DAC : CS4245_A_OUT_SEL_HIZ;
257 		cs4245_write_cached(chip, CS4245_SIGNAL_SEL, reg);
258 
259 		cs4245_write_cached(chip, CS4245_DAC_A_CTRL,
260 				    data->output_sel ? data->hp_vol_att : 0);
261 		cs4245_write_cached(chip, CS4245_DAC_B_CTRL,
262 				    data->output_sel ? data->hp_vol_att : 0);
263 
264 		oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
265 				      data->output_sel == 1 ? GPIO_HP_REAR : 0,
266 				      GPIO_HP_REAR);
267 	}
268 	mutex_unlock(&chip->mutex);
269 	return changed;
270 }
271 
272 static int hp_volume_offset_info(struct snd_kcontrol *ctl,
273 				 struct snd_ctl_elem_info *info)
274 {
275 	static const char *const names[3] = {
276 		"< 64 ohms", "64-150 ohms", "150-300 ohms"
277 	};
278 
279 	info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
280 	info->count = 1;
281 	info->value.enumerated.items = 3;
282 	if (info->value.enumerated.item >= 3)
283 		info->value.enumerated.item = 2;
284 	strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
285 	return 0;
286 }
287 
288 static int hp_volume_offset_get(struct snd_kcontrol *ctl,
289 				struct snd_ctl_elem_value *value)
290 {
291 	struct oxygen *chip = ctl->private_data;
292 	struct dg *data = chip->model_data;
293 
294 	mutex_lock(&chip->mutex);
295 	if (data->hp_vol_att > 2 * 7)
296 		value->value.enumerated.item[0] = 0;
297 	else if (data->hp_vol_att > 0)
298 		value->value.enumerated.item[0] = 1;
299 	else
300 		value->value.enumerated.item[0] = 2;
301 	mutex_unlock(&chip->mutex);
302 	return 0;
303 }
304 
305 static int hp_volume_offset_put(struct snd_kcontrol *ctl,
306 				struct snd_ctl_elem_value *value)
307 {
308 	static const s8 atts[3] = { 2 * 16, 2 * 7, 0 };
309 	struct oxygen *chip = ctl->private_data;
310 	struct dg *data = chip->model_data;
311 	s8 att;
312 	int changed;
313 
314 	if (value->value.enumerated.item[0] > 2)
315 		return -EINVAL;
316 	att = atts[value->value.enumerated.item[0]];
317 	mutex_lock(&chip->mutex);
318 	changed = att != data->hp_vol_att;
319 	if (changed) {
320 		data->hp_vol_att = att;
321 		if (data->output_sel) {
322 			cs4245_write_cached(chip, CS4245_DAC_A_CTRL, att);
323 			cs4245_write_cached(chip, CS4245_DAC_B_CTRL, att);
324 		}
325 	}
326 	mutex_unlock(&chip->mutex);
327 	return changed;
328 }
329 
330 static int input_vol_info(struct snd_kcontrol *ctl,
331 			  struct snd_ctl_elem_info *info)
332 {
333 	info->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
334 	info->count = 2;
335 	info->value.integer.min = 2 * -12;
336 	info->value.integer.max = 2 * 12;
337 	return 0;
338 }
339 
340 static int input_vol_get(struct snd_kcontrol *ctl,
341 			 struct snd_ctl_elem_value *value)
342 {
343 	struct oxygen *chip = ctl->private_data;
344 	struct dg *data = chip->model_data;
345 	unsigned int idx = ctl->private_value;
346 
347 	mutex_lock(&chip->mutex);
348 	value->value.integer.value[0] = data->input_vol[idx][0];
349 	value->value.integer.value[1] = data->input_vol[idx][1];
350 	mutex_unlock(&chip->mutex);
351 	return 0;
352 }
353 
354 static int input_vol_put(struct snd_kcontrol *ctl,
355 			 struct snd_ctl_elem_value *value)
356 {
357 	struct oxygen *chip = ctl->private_data;
358 	struct dg *data = chip->model_data;
359 	unsigned int idx = ctl->private_value;
360 	int changed = 0;
361 
362 	if (value->value.integer.value[0] < 2 * -12 ||
363 	    value->value.integer.value[0] > 2 * 12 ||
364 	    value->value.integer.value[1] < 2 * -12 ||
365 	    value->value.integer.value[1] > 2 * 12)
366 		return -EINVAL;
367 	mutex_lock(&chip->mutex);
368 	changed = data->input_vol[idx][0] != value->value.integer.value[0] ||
369 		  data->input_vol[idx][1] != value->value.integer.value[1];
370 	if (changed) {
371 		data->input_vol[idx][0] = value->value.integer.value[0];
372 		data->input_vol[idx][1] = value->value.integer.value[1];
373 		if (idx == data->input_sel) {
374 			cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
375 					    data->input_vol[idx][0]);
376 			cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
377 					    data->input_vol[idx][1]);
378 		}
379 	}
380 	mutex_unlock(&chip->mutex);
381 	return changed;
382 }
383 
384 static DECLARE_TLV_DB_SCALE(cs4245_pga_db_scale, -1200, 50, 0);
385 
386 static int input_sel_info(struct snd_kcontrol *ctl,
387 			  struct snd_ctl_elem_info *info)
388 {
389 	static const char *const names[4] = {
390 		"Mic", "Aux", "Front Mic", "Line"
391 	};
392 
393 	info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
394 	info->count = 1;
395 	info->value.enumerated.items = 4;
396 	info->value.enumerated.item &= 3;
397 	strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
398 	return 0;
399 }
400 
401 static int input_sel_get(struct snd_kcontrol *ctl,
402 			 struct snd_ctl_elem_value *value)
403 {
404 	struct oxygen *chip = ctl->private_data;
405 	struct dg *data = chip->model_data;
406 
407 	mutex_lock(&chip->mutex);
408 	value->value.enumerated.item[0] = data->input_sel;
409 	mutex_unlock(&chip->mutex);
410 	return 0;
411 }
412 
413 static int input_sel_put(struct snd_kcontrol *ctl,
414 			 struct snd_ctl_elem_value *value)
415 {
416 	static const u8 sel_values[4] = {
417 		CS4245_SEL_MIC,
418 		CS4245_SEL_INPUT_1,
419 		CS4245_SEL_INPUT_2,
420 		CS4245_SEL_INPUT_4
421 	};
422 	struct oxygen *chip = ctl->private_data;
423 	struct dg *data = chip->model_data;
424 	int changed;
425 
426 	if (value->value.enumerated.item[0] > 3)
427 		return -EINVAL;
428 
429 	mutex_lock(&chip->mutex);
430 	changed = value->value.enumerated.item[0] != data->input_sel;
431 	if (changed) {
432 		data->input_sel = value->value.enumerated.item[0];
433 
434 		cs4245_write(chip, CS4245_ANALOG_IN,
435 			     (data->cs4245_regs[CS4245_ANALOG_IN] &
436 							~CS4245_SEL_MASK) |
437 			     sel_values[data->input_sel]);
438 
439 		cs4245_write_cached(chip, CS4245_PGA_A_CTRL,
440 				    data->input_vol[data->input_sel][0]);
441 		cs4245_write_cached(chip, CS4245_PGA_B_CTRL,
442 				    data->input_vol[data->input_sel][1]);
443 
444 		oxygen_write16_masked(chip, OXYGEN_GPIO_DATA,
445 				      data->input_sel ? 0 : GPIO_INPUT_ROUTE,
446 				      GPIO_INPUT_ROUTE);
447 	}
448 	mutex_unlock(&chip->mutex);
449 	return changed;
450 }
451 
452 static int hpf_info(struct snd_kcontrol *ctl, struct snd_ctl_elem_info *info)
453 {
454 	static const char *const names[2] = { "Active", "Frozen" };
455 
456 	info->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
457 	info->count = 1;
458 	info->value.enumerated.items = 2;
459 	info->value.enumerated.item &= 1;
460 	strcpy(info->value.enumerated.name, names[info->value.enumerated.item]);
461 	return 0;
462 }
463 
464 static int hpf_get(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
465 {
466 	struct oxygen *chip = ctl->private_data;
467 	struct dg *data = chip->model_data;
468 
469 	value->value.enumerated.item[0] =
470 		!!(data->cs4245_regs[CS4245_ADC_CTRL] & CS4245_HPF_FREEZE);
471 	return 0;
472 }
473 
474 static int hpf_put(struct snd_kcontrol *ctl, struct snd_ctl_elem_value *value)
475 {
476 	struct oxygen *chip = ctl->private_data;
477 	struct dg *data = chip->model_data;
478 	u8 reg;
479 	int changed;
480 
481 	mutex_lock(&chip->mutex);
482 	reg = data->cs4245_regs[CS4245_ADC_CTRL] & ~CS4245_HPF_FREEZE;
483 	if (value->value.enumerated.item[0])
484 		reg |= CS4245_HPF_FREEZE;
485 	changed = reg != data->cs4245_regs[CS4245_ADC_CTRL];
486 	if (changed)
487 		cs4245_write(chip, CS4245_ADC_CTRL, reg);
488 	mutex_unlock(&chip->mutex);
489 	return changed;
490 }
491 
492 #define INPUT_VOLUME(xname, index) { \
493 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
494 	.name = xname, \
495 	.info = input_vol_info, \
496 	.get = input_vol_get, \
497 	.put = input_vol_put, \
498 	.tlv = { .p = cs4245_pga_db_scale }, \
499 	.private_value = index, \
500 }
501 static const struct snd_kcontrol_new dg_controls[] = {
502 	{
503 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
504 		.name = "Analog Output Playback Enum",
505 		.info = output_switch_info,
506 		.get = output_switch_get,
507 		.put = output_switch_put,
508 	},
509 	{
510 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
511 		.name = "Headphones Impedance Playback Enum",
512 		.info = hp_volume_offset_info,
513 		.get = hp_volume_offset_get,
514 		.put = hp_volume_offset_put,
515 	},
516 	INPUT_VOLUME("Mic Capture Volume", 0),
517 	INPUT_VOLUME("Aux Capture Volume", 1),
518 	INPUT_VOLUME("Front Mic Capture Volume", 2),
519 	INPUT_VOLUME("Line Capture Volume", 3),
520 	{
521 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
522 		.name = "Capture Source",
523 		.info = input_sel_info,
524 		.get = input_sel_get,
525 		.put = input_sel_put,
526 	},
527 	{
528 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
529 		.name = "ADC High-pass Filter Capture Enum",
530 		.info = hpf_info,
531 		.get = hpf_get,
532 		.put = hpf_put,
533 	},
534 };
535 
536 static int dg_control_filter(struct snd_kcontrol_new *template)
537 {
538 	if (!strncmp(template->name, "Master Playback ", 16))
539 		return 1;
540 	return 0;
541 }
542 
543 static int dg_mixer_init(struct oxygen *chip)
544 {
545 	unsigned int i;
546 	int err;
547 
548 	for (i = 0; i < ARRAY_SIZE(dg_controls); ++i) {
549 		err = snd_ctl_add(chip->card,
550 				  snd_ctl_new1(&dg_controls[i], chip));
551 		if (err < 0)
552 			return err;
553 	}
554 	return 0;
555 }
556 
557 static void dump_cs4245_registers(struct oxygen *chip,
558 				  struct snd_info_buffer *buffer)
559 {
560 	struct dg *data = chip->model_data;
561 	unsigned int i;
562 
563 	snd_iprintf(buffer, "\nCS4245:");
564 	for (i = 1; i <= 0x10; ++i)
565 		snd_iprintf(buffer, " %02x", data->cs4245_regs[i]);
566 	snd_iprintf(buffer, "\n");
567 }
568 
569 struct oxygen_model model_xonar_dg = {
570 	.shortname = "Xonar DG",
571 	.longname = "C-Media Oxygen HD Audio",
572 	.chip = "CMI8786",
573 	.init = dg_init,
574 	.control_filter = dg_control_filter,
575 	.mixer_init = dg_mixer_init,
576 	.cleanup = dg_cleanup,
577 	.suspend = dg_suspend,
578 	.resume = dg_resume,
579 	.set_dac_params = set_cs4245_dac_params,
580 	.set_adc_params = set_cs4245_adc_params,
581 	.dump_registers = dump_cs4245_registers,
582 	.model_data_size = sizeof(struct dg),
583 	.device_config = PLAYBACK_0_TO_I2S |
584 			 PLAYBACK_1_TO_SPDIF |
585 			 CAPTURE_0_FROM_I2S_1,
586 	.dac_channels_pcm = 6,
587 	.dac_channels_mixer = 0,
588 	.function_flags = OXYGEN_FUNCTION_SPI,
589 	.dac_mclks = OXYGEN_MCLKS(256, 128, 128),
590 	.adc_mclks = OXYGEN_MCLKS(256, 128, 128),
591 	.dac_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
592 	.adc_i2s_format = OXYGEN_I2S_FORMAT_LJUST,
593 };
594