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