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