xref: /minix/minix/drivers/audio/cs4281/cs4281.c (revision fb9c64b2)
1 #include "cs4281.h"
2 #include "mixer.h"
3 
4 /* global value */
5 DEV_STRUCT dev;
6 aud_sub_dev_conf_t aud_conf[3];
7 sub_dev_t sub_dev[3];
8 special_file_t special_file[3];
9 drv_t drv;
10 
11 /* internal function */
12 static int dev_probe(void);
13 static int set_sample_rate(u32_t rate, int num);
14 static int set_stereo(u32_t stereo, int num);
15 static int set_bits(u32_t bits, int sub_dev);
16 static int set_frag_size(u32_t frag_size, int num);
17 static int set_sign(u32_t val, int num);
18 static int get_frag_size(u32_t *val, int *len, int num);
19 static int free_buf(u32_t *val, int *len, int num);
20 
21 /* developer interface */
22 static int dev_reset(u32_t *base);
23 static void dev_configure(u32_t *base);
24 static void dev_init_mixer(u32_t *base);
25 static void dev_set_sample_rate(u32_t *base, u16_t sample_rate);
26 static void dev_set_format(u32_t *base, u32_t bits, u32_t sign,
27 							u32_t stereo, u32_t sample_count);
28 static void dev_start_channel(u32_t *base, int sub_dev);
29 static void dev_stop_channel(u32_t *base, int sub_dev);
30 static void dev_set_dma(u32_t *base, u32_t dma, u32_t len, int sub_dev);
31 static u32_t dev_read_dma_current(u32_t *base, int sub_dev);
32 static void dev_pause_dma(u32_t *base, int sub_dev);
33 static void dev_resume_dma(u32_t *base, int sub_dev);
34 static void dev_intr_other(u32_t *base, u32_t status);
35 static u32_t dev_read_clear_intr_status(u32_t *base);
36 static void dev_intr_enable(u32_t *base, int flag);
37 
38 /* ======= Developer implemented function ======= */
39 /* ====== Self-defined function ====== */
40 
41 /* ====== Mixer handling interface ======*/
42 /* Write the data to mixer register (### WRITE_MIXER_REG ###) */
43 void dev_mixer_write(u32_t *base, u32_t reg, u32_t val) {
44 	u32_t i, data, base0 = base[0];
45 	sdr_out32(base0, REG_CODEC_ADDR, reg);
46 	sdr_out32(base0, REG_CODEC_DATA, val);
47 	sdr_out32(base0, REG_CODEC_CTRL, 0x0e);
48 
49 	for (i = 0; i < 50000; i++) {
50 		micro_delay(10);
51 		data = sdr_in32(base0, REG_CODEC_CTRL);
52 		if (!(data & STS_CODEC_DONE))
53 			break;
54 	}
55 	if (i == 50000)
56 		printf("SDR: Codec is not ready in write\n");
57 }
58 
59 /* Read the data from mixer register (### READ_MIXER_REG ###) */
60 u32_t dev_mixer_read(u32_t *base, u32_t reg) {
61 	u32_t i, data, base0 = base[0];
62 	sdr_in32(base0, REG_CODEC_SDA);
63 	sdr_out32(base0, REG_CODEC_ADDR, reg & 0xff);
64 	sdr_out32(base0, REG_CODEC_DATA, 0);
65 	sdr_out32(base0, REG_CODEC_CTRL, 0x1e);
66 	for (i = 0; i < 50000; i++) {
67 		micro_delay(10);
68 		data = sdr_in32(base0, REG_CODEC_CTRL);
69 		if (!(data & STS_CODEC_DONE))
70 			break;
71 	}
72 	if (i == 50000)
73 		printf("SDR: Codec is not ready in read1\n");
74 	for (i = 0; i < 50000; i++) {
75 		micro_delay(10);
76 		data = sdr_in32(base0, REG_CODEC_STATUS);
77 		if (data & STS_CODEC_VALID)
78 			break;
79 	}
80 	if (i == 50000)
81 		printf("SDR: Codec is not ready in read2\n");
82 	return sdr_in32(base0, REG_CODEC_SDA);
83 }
84 
85 /* ====== Developer interface ======*/
86 
87 /* Reset the device (### RESET_HARDWARE_CAN_FAIL ###)
88  * -- Return OK means success, Others means failure */
89 static int dev_reset(u32_t *base) {
90 	u32_t data, base0 = base[0];
91 	data = sdr_in32(base0, REG_POWER_EXT);
92 	if (data & CMD_POWER_DOWN)
93 		sdr_out32(base0, REG_POWER_EXT, data & ~CMD_POWER_DOWN);
94 	data = sdr_in32(base0, REG_CONF_LOAD);
95 	if (data != 0x01)
96 		sdr_out32(base0, REG_CONF_LOAD, 0x01);
97 	sdr_out32(base0, REG_CONF_WRITE, 0x4281);
98 	sdr_out32(base0, REG_SOUND_POWER, 0x3f);
99 	sdr_out32(base0, REG_CLK_CTRL, 0);
100 	sdr_out32(base0, REG_MASTER_CTRL, 0);
101 	sdr_out32(base0, REG_CODEC_CTRL, 0);
102 	micro_delay(100);
103 	sdr_out32(base0, REG_SPOWER_CTRL, 0);
104 	micro_delay(100);
105 	sdr_out32(base0, REG_SPOWER_CTRL, 0x01);
106 	micro_delay(100);
107 	sdr_out32(base0, REG_MASTER_CTRL, 0x00010003);
108 	return OK;
109 }
110 
111 /* Configure hardware registers (### CONF_HARDWARE ###) */
112 static void dev_configure(u32_t *base) {
113 	u32_t i, data, base0 = base[0];
114 	sdr_out32(base0, REG_MASTER_CTRL, CMD_PORT_TIMING | CMD_AC97_MODE |
115 										CMD_MASTER_SERIAL);
116 	sdr_out32(base0, REG_CLK_CTRL, 0x10);
117 	micro_delay(50);
118 	sdr_out32(base0, REG_CLK_CTRL, 0x30);
119 	micro_delay(500);
120 	sdr_out32(base0, REG_CODEC_CTRL, 0x02);
121 	micro_delay(500);
122 	sdr_out32(base0, REG_CODEC_CTRL, 0x06);
123 	micro_delay(500);
124 	sdr_out32(base0, REG_CODEC_OSV, 0x03);
125 	sdr_out32(base0, REG_PCM_LVOL, 0x07);
126 	sdr_out32(base0, REG_PCM_RVOL, 0x07);
127 }
128 
129 /* Initialize the mixer (### INIT_MIXER ###) */
130 static void dev_init_mixer(u32_t *base) {
131 	dev_mixer_write(base, 0, 0);
132 }
133 
134 /* Set DAC and ADC sample rate (### SET_SAMPLE_RATE ###) */
135 static void dev_set_sample_rate(u32_t *base, u16_t sample_rate) {
136 	u32_t i, data = 0, base0 = base[0];
137 	for (i = 0; i < 6; i++) {
138 		if (g_sample_rate[i] == sample_rate) {
139 			data = i;
140 			break;
141 		}
142 	}
143 	sdr_out32(base0, REG_DAC_SAMPLE_RATE, data);
144 	sdr_out32(base0, REG_ADC_SAMPLE_RATE, data);
145 }
146 
147 /* Set DAC and ADC format (### SET_FORMAT ###)*/
148 static void dev_set_format(u32_t *base, u32_t bits, u32_t sign,
149 							u32_t stereo, u32_t sample_count) {
150 	u32_t base0 = base[0];
151 	dmr_data = CMD_DMR_INIT;
152 	if (stereo == 0)
153 		dmr_data |= CMD_DMR_MONO;
154 	if (sign == 0)
155 		dmr_data |= CMD_DMR_UNSIGN;
156 	if (bits == 8) {
157 		dmr_data |= CMD_DMR_BIT8;
158 		if (stereo == 0)
159 			dmr_data |= CMD_DMR_SWAP;
160 	}
161 	else if (bits == 32)
162 		dmr_data |= CMD_DMR_BIT32;
163 }
164 
165 /* Start the channel (### START_CHANNEL ###) */
166 static void dev_start_channel(u32_t *base, int sub_dev) {
167 	u32_t temp, base0 = base[0];
168 
169 	dcr_data = 0x30001;
170 	if (sub_dev == DAC)
171 		fcr_data = CMD_DAC_FCR_INIT;
172 	if (sub_dev == ADC)
173 		fcr_data = CMD_ADC_FCR_INIT;
174 	dmr_data |= CMD_DMR_DMA;
175 	dcr_data &= ~CMD_DCR_MASK;
176 	fcr_data |= CMD_FCR_FEN;
177 	if (sub_dev == DAC) {
178 		dmr_data |= CMD_DMR_WRITE;
179 		sdr_out32(base0, REG_DAC_FSIC, 0);
180 		sdr_out32(base0, REG_DAC_DMR, dmr_data & ~CMD_DMR_DMA);
181 		sdr_out32(base0, REG_DAC_DMR, dmr_data);
182 		sdr_out32(base0, REG_DAC_FCR, fcr_data);
183 		sdr_out32(base0, REG_DAC_DCR, dcr_data);
184 	}
185 	else if (sub_dev == ADC) {
186 		dmr_data |= CMD_DMR_READ;
187 		sdr_out32(base0, REG_ADC_FSIC, 0);
188 		sdr_out32(base0, REG_ADC_DMR, dmr_data & ~CMD_DMR_DMA);
189 		sdr_out32(base0, REG_ADC_DMR, dmr_data);
190 		sdr_out32(base0, REG_ADC_FCR, fcr_data);
191 		sdr_out32(base0, REG_ADC_DCR, dcr_data);
192 	}
193 
194 }
195 
196 /* Stop the channel (### STOP_CHANNEL ###) */
197 static void dev_stop_channel(u32_t *base, int sub_dev) {
198 	u32_t base0 = base[0];
199 	dmr_data &= ~(CMD_DMR_DMA | CMD_DMR_POLL);
200 	dcr_data |= ~CMD_DCR_MASK;
201 	fcr_data &= ~CMD_FCR_FEN;
202 	if (sub_dev == DAC) {
203 		sdr_out32(base0, REG_DAC_DMR, dmr_data);
204 		sdr_out32(base0, REG_DAC_FCR, fcr_data);
205 		sdr_out32(base0, REG_DAC_DCR, dcr_data);
206 	}
207 	else if (sub_dev == ADC) {
208 		sdr_out32(base0, REG_ADC_DMR, dmr_data);
209 		sdr_out32(base0, REG_ADC_FCR, fcr_data);
210 		sdr_out32(base0, REG_ADC_DCR, dcr_data);
211 	}
212 }
213 
214 /* Set DMA address and length (### SET_DMA ###) */
215 static void dev_set_dma(u32_t *base, u32_t dma, u32_t len, int sub_dev) {
216 	u32_t base0 = base[0];
217 
218 	if (sub_dev == DAC) {
219 		sdr_out32(base0, REG_DAC_DMA_ADDR, dma);
220 		sdr_out32(base0, REG_DAC_DMA_LEN, len - 1);
221 	}
222 	else if (sub_dev == ADC) {
223 		sdr_out32(base0, REG_ADC_DMA_ADDR, dma);
224 		sdr_out32(base0, REG_ADC_DMA_LEN, len - 1);
225 	}
226 }
227 
228 /* Read current address (### READ_DMA_CURRENT_ADDR ###) */
229 static u32_t dev_read_dma_current(u32_t *base, int sub_dev) {
230 	u32_t data, base0 = base[0];
231 	if (sub_dev == DAC)
232 		data = sdr_in32(base0, REG_DAC_DCC);
233 	else if (sub_dev == ADC)
234 		data = sdr_in16(base0, REG_ADC_DCC);
235 	data &= 0xffff;
236 	return (u16_t)data;
237 }
238 
239 /* Pause the DMA (### PAUSE_DMA ###) */
240 static void dev_pause_dma(u32_t *base, int sub_dev) {
241 	u32_t base0 = base[0];
242 	dcr_data |= CMD_DCR_MASK;
243 	fcr_data |= CMD_FCR_FEN;
244 	if (sub_dev == DAC) {
245 		sdr_out32(base0, REG_DAC_DMR, dmr_data);
246 		sdr_out32(base0, REG_DAC_FCR, fcr_data);
247 		sdr_out32(base0, REG_DAC_DCR, dcr_data);
248 	}
249 	if (sub_dev == ADC) {
250 		sdr_out32(base0, REG_ADC_DMR, dmr_data);
251 		sdr_out32(base0, REG_ADC_FCR, fcr_data);
252 		sdr_out32(base0, REG_ADC_DCR, dcr_data);
253 	}
254 }
255 
256 /* Resume the DMA (### RESUME_DMA ###) */
257 static void dev_resume_dma(u32_t *base, int sub_dev) {
258 	u32_t base0 = base[0];
259 	dcr_data &= ~CMD_DCR_MASK;
260 	fcr_data &= ~CMD_FCR_FEN;
261 	if (sub_dev == DAC) {
262 		sdr_out32(base0, REG_DAC_DMR, dmr_data);
263 		sdr_out32(base0, REG_DAC_FCR, fcr_data);
264 		sdr_out32(base0, REG_DAC_DCR, dcr_data);
265 	}
266 	if (sub_dev == ADC) {
267 		sdr_out32(base0, REG_ADC_DMR, dmr_data);
268 		sdr_out32(base0, REG_ADC_FCR, fcr_data);
269 		sdr_out32(base0, REG_ADC_DCR, dcr_data);
270 	}
271 }
272 
273 /* Read and clear interrupt stats (### READ_CLEAR_INTR_STS ###)
274  * -- Return interrupt status */
275 static u32_t dev_read_clear_intr_status(u32_t *base) {
276 	u32_t status, base0 = base[0];
277 	status = sdr_in32(base0, REG_INTR_STS);
278 	sdr_in32(base0, REG_DAC_HDSR);
279 	sdr_in32(base0, REG_ADC_HDSR);
280 	sdr_out32(base0, REG_INTR_CTRL, CMD_INTR_ENABLE);
281 	return status;
282 }
283 
284 /* Enable or disable interrupt (### INTR_ENABLE_DISABLE ###) */
285 static void dev_intr_enable(u32_t *base, int flag) {
286 	u32_t data, base0 = base[0];
287 	if (flag == INTR_ENABLE) {
288 		sdr_out32(base0, REG_INTR_CTRL, CMD_INTR_ENABLE);
289 		sdr_out32(base0, REG_INTR_MASK, ~(CMD_INTR_DMA | CMD_INTR_DMA0 |
290 										CMD_INTR_DMA1));
291 	}
292 	else if (flag == INTR_DISABLE) {
293 		sdr_out32(base0, REG_INTR_CTRL, ~CMD_INTR_ENABLE);
294 		sdr_out32(base0, REG_INTR_MASK, 0x7fffffff);
295 	}
296 }
297 
298 /* ======= Common driver function ======= */
299 /* Probe the device */
300 static int dev_probe(void) {
301 	int devind, i, ioflag;
302 	u32_t device, bar, size, base;
303 	u16_t vid, did, temp;
304 	u8_t *reg;
305 
306 	pci_init();
307 	device = pci_first_dev(&devind, &vid, &did);
308 	while (device > 0) {
309 		if (vid == VENDOR_ID && did == DEVICE_ID)
310 			break;
311 		device = pci_next_dev(&devind, &vid, &did);
312 	}
313 	if (vid != VENDOR_ID || did != DEVICE_ID)
314 		return EIO;
315 	pci_reserve(devind);
316 
317 	for (i = 0; i < 6; i++)
318 		dev.base[i] = 0;
319 #ifdef DMA_BASE_IOMAP
320 	for (i = 0; i < 6; i++) {
321 		if (pci_get_bar(devind, PCI_BAR + i * 4, &base, &size, &ioflag)) {
322 			/* printf("SDR: Fail to get PCI BAR %d\n", i); */
323 			continue;
324 		}
325 		if (ioflag) {
326 			/* printf("SDR: PCI BAR %d is not for memory\n", i); */
327 			continue;
328 		}
329 		if ((reg = vm_map_phys(SELF, (void *)base, size)) == MAP_FAILED) {
330 			printf("SDR: Fail to map hardware registers from PCI\n");
331 			return -EIO;
332 		}
333 		dev.base[i] = (u32_t)reg;
334 	}
335 #else
336 	/* Get PCI BAR0-5 */
337 	for (i = 0; i < 6; i++)
338 		dev.base[i] = pci_attr_r32(devind, PCI_BAR + i * 4) & 0xffffffe0;
339 #endif
340 	dev.name = pci_dev_name(vid, did);
341 	dev.irq = pci_attr_r8(devind, PCI_ILR);
342 	dev.revision = pci_attr_r8(devind, PCI_REV);
343 	dev.did = did;
344 	dev.vid = vid;
345 	dev.devind = devind;
346 	temp = pci_attr_r16(devind, PCI_CR);
347 	pci_attr_w16(devind, PCI_CR, temp | 0x105);
348 
349 #ifdef MY_DEBUG
350 	printf("SDR: Hardware name is %s\n", dev.name);
351 	for (i = 0; i < 6; i++)
352 		printf("SDR: PCI BAR%d is 0x%08x\n", i, dev.base[i]);
353 	printf("SDR: IRQ number is 0x%02x\n", dev.irq);
354 #endif
355 	return OK;
356 }
357 
358 /* Set sample rate in configuration */
359 static int set_sample_rate(u32_t rate, int num) {
360 	aud_conf[num].sample_rate = rate;
361 	return OK;
362 }
363 
364 /* Set stereo in configuration */
365 static int set_stereo(u32_t stereo, int num) {
366 	aud_conf[num].stereo = stereo;
367 	return OK;
368 }
369 
370 /* Set sample bits in configuration */
371 static int set_bits(u32_t bits, int num) {
372 	aud_conf[num].nr_of_bits = bits;
373 	return OK;
374 }
375 
376 /* Set fragment size in configuration */
377 static int set_frag_size(u32_t frag_size, int num) {
378 	if (frag_size > (sub_dev[num].DmaSize / sub_dev[num].NrOfDmaFragments) ||
379 		frag_size < sub_dev[num].MinFragmentSize) {
380 		return EINVAL;
381 	}
382 	aud_conf[num].fragment_size = frag_size;
383 	return OK;
384 }
385 
386 /* Set frame sign in configuration */
387 static int set_sign(u32_t val, int num) {
388 	aud_conf[num].sign = val;
389 	return OK;
390 }
391 
392 /* Get maximum fragment size */
393 static int get_max_frag_size(u32_t *val, int *len, int num) {
394 	*len = sizeof(*val);
395 	*val = (sub_dev[num].DmaSize / sub_dev[num].NrOfDmaFragments);
396 	return OK;
397 }
398 
399 /* Return 1 if there are free buffers */
400 static int free_buf(u32_t *val, int *len, int num) {
401 	*len = sizeof(*val);
402 	if (sub_dev[num].BufLength == sub_dev[num].NrOfExtraBuffers)
403 		*val = 0;
404 	else
405 		*val = 1;
406 	return OK;
407 }
408 
409 /* Get the current sample counter */
410 static int get_samples_in_buf(u32_t *result, int *len, int chan) {
411 	u32_t res;
412 	/* READ_DMA_CURRENT_ADDR */
413 	res = dev_read_dma_current(dev.base, chan);
414 	*result = (u32_t)(sub_dev[chan].BufLength * 8192) + res;
415 	return OK;
416 }
417 
418 /* ======= [Audio interface] Initialize data structure ======= */
419 int drv_init(void) {
420 	drv.DriverName = DRIVER_NAME;
421 	drv.NrOfSubDevices = 3;
422 	drv.NrOfSpecialFiles = 3;
423 
424 	sub_dev[DAC].readable = 0;
425 	sub_dev[DAC].writable = 1;
426 	sub_dev[DAC].DmaSize = 64 * 1024;
427 	sub_dev[DAC].NrOfDmaFragments = 2;
428 	sub_dev[DAC].MinFragmentSize = 1024;
429 	sub_dev[DAC].NrOfExtraBuffers = 4;
430 
431 	sub_dev[ADC].readable = 1;
432 	sub_dev[ADC].writable = 0;
433 	sub_dev[ADC].DmaSize = 64 * 1024;
434 	sub_dev[ADC].NrOfDmaFragments = 2;
435 	sub_dev[ADC].MinFragmentSize = 1024;
436 	sub_dev[ADC].NrOfExtraBuffers = 4;
437 
438 	sub_dev[MIX].writable = 0;
439 	sub_dev[MIX].readable = 0;
440 
441 	special_file[0].minor_dev_nr = 0;
442 	special_file[0].write_chan = DAC;
443 	special_file[0].read_chan = NO_CHANNEL;
444 	special_file[0].io_ctl = DAC;
445 
446 	special_file[1].minor_dev_nr = 1;
447 	special_file[1].write_chan = NO_CHANNEL;
448 	special_file[1].read_chan = ADC;
449 	special_file[1].io_ctl = ADC;
450 
451 	special_file[2].minor_dev_nr = 2;
452 	special_file[2].write_chan = NO_CHANNEL;
453 	special_file[2].read_chan = NO_CHANNEL;
454 	special_file[2].io_ctl = MIX;
455 
456 	return OK;
457 }
458 
459 /* ======= [Audio interface] Initialize hardware ======= */
460 int drv_init_hw(void) {
461 	int i;
462 
463 	/* Match the device */
464 	if (dev_probe()) {
465 		printf("SDR: No sound card found\n");
466 		return EIO;
467 	}
468 
469 	/* Reset the device */
470 	/* ### RESET_HARDWARE_CAN_FAIL ### */
471 	if (dev_reset(dev.base)) {
472 		printf("SDR: Fail to reset the device\n");
473 		return EIO;
474 	}
475 
476 	/* Configure the hardware */
477 	/* ### CONF_HARDWARE ### */
478 	dev_configure(dev.base);
479 
480 	/* Initialize the mixer */
481 	/* ### INIT_MIXER ### */
482 	dev_init_mixer(dev.base);
483 
484 	/* Set default mixer volume */
485 	dev_set_default_volume(dev.base);
486 
487 	/* Initialize subdevice data */
488 	for (i = 0; i < drv.NrOfSubDevices; i++) {
489 		if (i == MIX)
490 			continue;
491 		aud_conf[i].busy = 0;
492 		aud_conf[i].stereo = 1;
493 		aud_conf[i].sample_rate = 44100;
494 		aud_conf[i].nr_of_bits = 16;
495 		aud_conf[i].sign = 1;
496 		aud_conf[i].fragment_size =
497 			sub_dev[i].DmaSize / sub_dev[i].NrOfDmaFragments;
498 	}
499 	return OK;
500 }
501 
502 /* ======= [Audio interface] Driver reset =======*/
503 int drv_reset(void) {
504 	/* ### RESET_HARDWARE_CAN_FAIL ### */
505 	return dev_reset(dev.base);
506 }
507 
508 /* ======= [Audio interface] Driver start ======= */
509 int drv_start(int sub_dev, int DmaMode) {
510 	int sample_count;
511 
512 	/* Set DAC and ADC sample rate */
513 	/* ### SET_SAMPLE_RATE ### */
514 	dev_set_sample_rate(dev.base, aud_conf[sub_dev].sample_rate);
515 
516 	sample_count = aud_conf[sub_dev].fragment_size;
517 #ifdef DMA_LENGTH_BY_FRAME
518 	sample_count = sample_count / (aud_conf[sub_dev].nr_of_bits * (aud_conf[sub_dev].stereo + 1) / 8);
519 #endif
520 	/* Set DAC and ADC format */
521 	/* ### SET_FORMAT ### */
522 	dev_set_format(dev.base, aud_conf[sub_dev].nr_of_bits,
523 			aud_conf[sub_dev].sign, aud_conf[sub_dev].stereo, sample_count);
524 
525 	drv_reenable_int(sub_dev);
526 
527 	/* Start the channel */
528 	/* ### START_CHANNEL ### */
529 	dev_start_channel(dev.base, sub_dev);
530 	aud_conf[sub_dev].busy = 1;
531 
532 	return OK;
533 }
534 
535 /* ======= [Audio interface] Driver start ======= */
536 int drv_stop(int sub_dev) {
537 	u32_t data;
538 
539 	/* INTR_ENABLE_DISABLE */
540 	dev_intr_enable(dev.base, INTR_DISABLE);
541 
542 	/* ### STOP_CHANNEL ### */
543 	dev_stop_channel(dev.base, sub_dev);
544 
545 	aud_conf[sub_dev].busy = 0;
546 	return OK;
547 }
548 
549 /* ======= [Audio interface] Enable interrupt ======= */
550 int drv_reenable_int(int chan) {
551 	/* INTR_ENABLE_DISABLE */
552 	dev_intr_enable(dev.base, INTR_ENABLE);
553 	return OK;
554 }
555 
556 /* ======= [Audio interface] I/O control ======= */
557 int drv_io_ctl(unsigned long request, void *val, int *len, int sub_dev) {
558 	int status;
559 	switch (request) {
560 		case DSPIORATE:
561 			status = set_sample_rate(*((u32_t *)val), sub_dev);
562 			break;
563 		case DSPIOSTEREO:
564 			status = set_stereo(*((u32_t *)val), sub_dev);
565 			break;
566 		case DSPIOBITS:
567 			status = set_bits(*((u32_t *)val), sub_dev);
568 			break;
569 		case DSPIOSIZE:
570 			status = set_frag_size(*((u32_t *)val), sub_dev);
571 			break;
572 		case DSPIOSIGN:
573 			status = set_sign(*((u32_t *)val), sub_dev);
574 			break;
575 		case DSPIOMAX:
576 			status = get_max_frag_size(val, len, sub_dev);
577 			break;
578 		case DSPIORESET:
579 			status = drv_reset();
580 			break;
581 		case DSPIOFREEBUF:
582 			status = free_buf(val, len, sub_dev);
583 			break;
584 		case DSPIOSAMPLESINBUF:
585 			status = get_samples_in_buf(val, len, sub_dev);
586 			break;
587 		case DSPIOPAUSE:
588 			status = drv_pause(sub_dev);
589 			break;
590 		case DSPIORESUME:
591 			status = drv_resume(sub_dev);
592 			break;
593 		case MIXIOGETVOLUME:
594 			/* ### GET_SET_VOLUME ### */
595 			status = get_set_volume(dev.base, val, GET_VOL);
596 			break;
597 		case MIXIOSETVOLUME:
598 			/* ### GET_SET_VOLUME ### */
599 			status = get_set_volume(dev.base, val, SET_VOL);
600 			break;
601 		default:
602 			status = EINVAL;
603 			break;
604 	}
605 	return status;
606 }
607 
608 /* ======= [Audio interface] Get request number ======= */
609 int drv_get_irq(char *irq) {
610 	*irq = dev.irq;
611 	return OK;
612 }
613 
614 /* ======= [Audio interface] Get fragment size ======= */
615 int drv_get_frag_size(u32_t *frag_size, int sub_dev) {
616 	*frag_size = aud_conf[sub_dev].fragment_size;
617 	return OK;
618 }
619 
620 /* ======= [Audio interface] Set DMA channel ======= */
621 int drv_set_dma(u32_t dma, u32_t length, int chan) {
622 #ifdef DMA_LENGTH_BY_FRAME
623 	length = length / (aud_conf[chan].nr_of_bits * (aud_conf[chan].stereo + 1) / 8);
624 #endif
625 	/* ### SET_DMA ### */
626 	dev_set_dma(dev.base, dma, length, chan);
627 	return OK;
628 }
629 
630 /* ======= [Audio interface] Get interrupt summary status ======= */
631 int drv_int_sum(void) {
632 	u32_t status;
633 	/* ### READ_CLEAR_INTR_STS ### */
634 	status = dev_read_clear_intr_status(dev.base);
635 	dev.intr_status = status;
636 #ifdef MY_DEBUG
637 	printf("SDR: Interrupt status is 0x%08x\n", status);
638 #endif
639 	return (status & (INTR_STS_DAC | INTR_STS_ADC));
640 }
641 
642 /* ======= [Audio interface] Handle interrupt status ======= */
643 int drv_int(int sub_dev) {
644 	u32_t mask;
645 
646 	/* ### CHECK_INTR_DAC ### */
647 	if (sub_dev == DAC)
648 		mask = INTR_STS_DAC;
649 	/* ### CHECK_INTR_ADC ### */
650 	else if (sub_dev == ADC)
651 		mask = INTR_STS_ADC;
652 	else
653 		return 0;
654 
655 	return dev.intr_status & mask;
656 }
657 
658 /* ======= [Audio interface] Pause DMA ======= */
659 int drv_pause(int sub_dev) {
660 	/* ### PAUSE_DMA ### */
661 	dev_pause_dma(dev.base, sub_dev);
662 	return OK;
663 }
664 
665 /* ======= [Audio interface] Resume DMA ======= */
666 int drv_resume(int sub_dev) {
667 	/* ### RESUME_DMA ### */
668 	dev_resume_dma(dev.base, sub_dev);
669 	return OK;
670 }
671