Added K70f120 project, set default playback to DAC
[pcm-lib.git] / source / soc-codec / Kinets / kinets-k60dac.c
blob305213f7f78cf6a638d34f1c4089f325bf5b2abc
1 /*
2 * kinets-K60dac.c -- SoC audio for kinets tower boards with
3 * dac0 and dac1 (44100HZ ,16bit,2channel)
5 */
7 #include "pcm.h"
9 #ifdef KINETS_K60DAC
11 #include "kinets-k60dac.h"
13 #if defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */
14 #pragma data_alignment=32
15 static DMA_TCD_t tcd_list0[MAX_TCD_LISTS];
16 #pragma data_alignment=32
17 static DMA_TCD_t tcd_list1[MAX_TCD_LISTS];
18 #else /*elif defined ( __GNUC__ )*/ /* GCC CS3 2009q3-68 */
19 /*static*/ DMA_TCD_t tcd_list0[MAX_TCD_LISTS] __attribute__ ((aligned (32)));
20 /*static*/ DMA_TCD_t tcd_list1[MAX_TCD_LISTS] __attribute__ ((aligned (32)));
21 #endif
23 static void dma_load_td_chain(unsigned int ch, DMA_TCD_p tcd_list);
24 static void dacc_init(struct snd_pcm_runtime *runtime,uint_8 BuffMode,uint_8 Vreference,
25 uint_8 TrigMode, uint_8 BuffInitPos, uint_8 BuffUpLimit,uint_8 WatermarkMode);
26 static void dacc_deinit(struct snd_pcm_runtime *runtime);
27 static int dac_digital_mute(int mute);
28 static int preinit_params(struct snd_pcm_runtime *runtime, struct snd_pcm_params *params);
29 static int codec_pcm_interface_params(struct snd_pcm_runtime *runtime,
30 struct snd_pcm_params *params);
31 static int cpu_interface_params(struct snd_pcm_runtime *runtime, struct snd_pcm_params *params);
32 static int dma_pcm_params(struct snd_pcm_runtime *runtime, struct snd_pcm_params *params);
33 static void dma_start_channel(unsigned int ch);
34 static void dma_stop_channel(unsigned int ch);
35 static inline unsigned short dac_format_in_data (struct snd_pcm_runtime *runtime, uint16_t *inbuf);
38 /* ticks implement */
39 /* now return is system elapsed ms */
40 unsigned int get_curr_ticks(void)
42 TIME_STRUCT tm;
43 MQX_TICK_STRUCT tick1;
45 _time_get_elapsed_ticks(&tick1);
46 /* _time_diff_ticks(&tick2, &tick1, &tick3); */
47 _ticks_to_time(&tick1,&tm);
48 /* os_printf("%d-%d \n",tm.SECONDS,tm.MILLISECONDS); */
49 return (tm.SECONDS * 1000 + tm.MILLISECONDS);
52 unsigned int get_hz(void)
54 return /* _time_get_ticks_per_sec()*/1000;
57 void sco_msleep(unsigned int ms)
59 unsigned int ticks = ms / (1000/_time_get_ticks_per_sec());
60 if(ticks == 0)
61 ticks = 1;
62 _time_delay(ticks);
65 void sco_pcm_lock(void)
67 _bsp_int_disable(_bsp_get_edma_done_vector(0));
68 _bsp_int_disable(_bsp_get_edma_done_vector(1));
69 //_int_disable();
72 void sco_pcm_unlock(void)
74 _bsp_int_enable(_bsp_get_edma_done_vector(0));
75 _bsp_int_enable(_bsp_get_edma_done_vector(1));
76 //_int_enable();
79 static struct soc_dma_data edma_data[2]; /* play and capture */
81 int sco_pcm_open(struct snd_pcm_runtime *runtime)
83 int ret = 0;
85 //os_mutex_lock(&pcm_mutex);
87 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *) runtime->private_data;
88 struct soc_dma_data * dma_data;
91 /* don't allocat ,use gloabal */
92 iprtd->dma_data = (void *)(&edma_data[runtime->stream]);
93 os_memset(iprtd->dma_data, 0, sizeof(struct soc_dma_data));
95 dma_data = (struct soc_dma_data *)iprtd->dma_data;
96 dma_data->dac0_base = DAC0_BASE_PTR;
97 dma_data->dac1_base = DAC1_BASE_PTR;
99 /* codec ,power, path init at this */
101 /* startup the audio subsystem sequence */
102 /* -> dma -> dac -> misc */
103 dacc_init(runtime,DAC_BF_NORMAL_MODE,DAC_SEL_VDDA,
104 DAC_SEL_PDB_HW_TRIG,DAC_SET_PTR_AT_BF(0),DAC_SET_PTR_UP_LIMIT(15),DAC_BFWM_4WORDS);
106 //os_mutex_unlock(&pcm_mutex);
108 return ret;
111 int sco_pcm_prepare(struct snd_pcm_runtime *runtime)
113 int ret = 0;
115 //os_mutex_lock(&pcm_mutex);
116 /* dma prepare => dac prepare */
117 dac_digital_mute(0);
118 //os_mutex_unlock(&pcm_mutex);
120 out:
121 return ret;
124 int sco_pcm_close(struct snd_pcm_runtime *runtime)
126 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *)runtime->private_data;
127 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
129 //os_mutex_lock(&pcm_mutex);
130 if (runtime->stream == SNDRV_PCM_STREAM_PLAYBACK) /* only playback */
131 dac_digital_mute(0);
133 dacc_deinit(runtime);
135 /* sequence of close
136 cpu pcm interface -> codec -> dma */
138 //PCM_mem_free(dma_data); // don't free, use global
139 iprtd->dma_data = NULL;
141 if(runtime->dma_area)
142 PCM_mem_free(runtime->dma_area);
144 /* at this can free runtime member => struct sco_pcm_runtime_data *iprtd */
145 //os_mutex_unlock(&pcm_mutex);
146 return 0;
149 int sco_pcm_params(struct snd_pcm_runtime *runtime,
150 struct snd_pcm_params *params)
152 int ret = 0;
154 // os_mutex_lock(&pcm_mutex);
155 /* set paramaters before codec and dma set it */
156 ret = preinit_params(runtime,params); /* preinit_params can move to sco_pcm_open */
157 if (ret < 0) {
158 printf("soc: preinit set params failed\n");
159 goto out;
162 /* code interface set params */
163 ret = codec_pcm_interface_params(runtime,params);
164 if (ret < 0) {
165 printf("soc: can't set codec params\n");
166 goto codec_err;
169 /* cpu interface set params */
170 ret = cpu_interface_params(runtime,params);
171 if (ret < 0) {
172 printf("soc: interface set params failed\n");
173 goto interface_err;
176 ret = dma_pcm_params(runtime,params);
177 if (ret < 0) {
178 printf("soc: dma set params failed\n");
179 goto dma_err;
182 /* statue to SNDRV_PCM_STATE_SETUP after params setup complete */
183 // snd_pcm_drop(runtime); // fixme use drop before the prepare,fail
184 runtime->status->state = SNDRV_PCM_STATE_SETUP;
186 out:
187 //os_mutex_unlock(&pcm_mutex);
188 return ret;
190 dma_err:
192 interface_err:
194 codec_err:
196 //os_mutex_unlock(&pcm_mutex);
197 return ret;
200 /* dma operation functions */
201 /******************************************************************************/
202 int sco_pcm_trigger(struct snd_pcm_runtime *runtime, int cmd)
204 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *) runtime->private_data;
205 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
206 int ret;
207 /* cmd handle sequance : codec => edma => ssi */
208 switch (cmd) {
209 case SNDRV_PCM_TRIGGER_START:
210 case SNDRV_PCM_TRIGGER_RESUME:
211 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
213 //edma_start(SSI_TX_DMA_CHN); // fixme only star tx
214 //DAC_C0_REG(dma_data->dac0_base) |= ((DAC_C0_DACEN_MASK));
215 #ifdef DAC_TWO_CHANNEL
216 // DAC_C0_REG(dma_data->dac1_base) |= ((DAC_C0_DACEN_MASK));
217 #endif
218 PDB0_DACINTC0 |= PDB_DACINTC0_TOE_MASK ;
219 #ifdef DAC_TWO_CHANNEL
220 PDB0_DACINTC1 |= PDB_DACINTC0_TOE_MASK ;
221 #endif
222 dma_start_channel(DMA_CHANNEL_DAC0);
223 #ifdef DAC_TWO_CHANNEL
224 dma_start_channel(DMA_CHANNEL_DAC1);
225 #endif
227 PDB0_SC |= PDB_SC_SWTRIG_MASK ;
228 break;
230 case SNDRV_PCM_TRIGGER_STOP:
231 case SNDRV_PCM_TRIGGER_SUSPEND:
232 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
233 //PDB0_SC &= (~PDB_SC_SWTRIG_MASK) ;
234 dma_stop_channel(DMA_CHANNEL_DAC0);
235 #ifdef DAC_TWO_CHANNEL
236 dma_stop_channel(DMA_CHANNEL_DAC1);
237 #endif
238 PDB0_DACINTC0 &= ~PDB_DACINTC0_TOE_MASK;
239 #ifdef DAC_TWO_CHANNEL
240 PDB0_DACINTC1 &= ~PDB_DACINTC0_TOE_MASK ;
241 #endif
242 //DAC_C0_REG(dma_data->dac0_base) &= (~(DAC_C0_DACEN_MASK));
243 #ifdef DAC_TWO_CHANNEL
244 //DAC_C0_REG(dma_data->dac1_base) &= (~(DAC_C0_DACEN_MASK));
245 #endif
246 break;
247 default:
248 return -1;
251 return 0;
254 int sco_pcm_stream_copy (struct snd_pcm_runtime *runtime, int channel, snd_pcm_uframes_t hwoff, char *buf, snd_pcm_uframes_t count)
256 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *)runtime->private_data;
257 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
259 unsigned short * hwbuf_ch0 = (unsigned short *)((char *)iprtd->buf + frames_to_bytes(runtime, hwoff) / 2);
260 #ifdef DAC_TWO_CHANNEL
261 unsigned short * hwbuf_ch1 = (unsigned short *) ((char *) hwbuf_ch0 + runtime->dma_bytes / 2);
262 #endif
263 uint16_t *inbuf = (uint16_t *)buf;
265 for(int i = 0; i < (count); i++) {
266 //os_memcpy(hwbuf, buf, frames_to_bytes(runtime, frames));
267 *hwbuf_ch0 = dac_format_in_data(runtime, &inbuf[i*2]);
268 hwbuf_ch0 ++;
269 #ifdef DAC_TWO_CHANNEL
270 *hwbuf_ch1 = dac_format_in_data(runtime, &inbuf[i*2 + 1] /* samplebits 16 => 2bytes*/);
271 hwbuf_ch1 ++;
272 #endif
274 return 0;
277 static void dacc_init(struct snd_pcm_runtime *runtime,uint_8 BuffMode,uint_8 Vreference,
278 uint_8 TrigMode, uint_8 BuffInitPos, uint_8 BuffUpLimit,uint_8 WatermarkMode)
280 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *)runtime->private_data;
281 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
282 DAC_MemMapPtr dac0_ptr = dma_data->dac0_base;
283 DAC_MemMapPtr dac1_ptr = dma_data->dac1_base;
284 uint32_t regval;
286 SIM_SCGC2 |= (SIM_SCGC2_DAC0_MASK | SIM_SCGC2_DAC1_MASK); // Allow clock to enable DAC0 ,DAC1
288 regval = (
289 #ifdef DAM16WORD_TWICE
290 DAC_BFB_PTR_INT_DISABLE |
291 DAC_BFT_PTR_INT_ENABLE |
292 DAC_BFWM_INT_ENABLE |
293 #else
294 DAC_BFB_PTR_INT_ENABLE |
295 DAC_BFT_PTR_INT_DISABLE |
296 DAC_BFWM_INT_DISABLE |
297 #endif
298 DAC_HP_MODE |
299 DAC_SW_TRIG_STOP |
300 TrigMode |
301 Vreference |
302 DAC_ENABLE
303 /* DAC_DISABLE */
306 DAC_C0_REG(dac0_ptr) = regval;
307 #ifdef DAC_TWO_CHANNEL
308 DAC_C0_REG(dac1_ptr) = regval;
309 #endif
311 if (Vreference == DAC_SEL_VREFO ) {
312 SIM_SCGC4 |= !SIM_SCGC4_VREF_MASK ;
313 VREF_SC = 0x82;
314 while (!(VREF_SC & VREF_SC_VREFST_MASK) ){}
317 regval = (
318 DAC_C1_DMAEN_MASK | /* dac dma mode */
319 DAC_BF_ENABLE | //Buffer Enabled
320 WatermarkMode | // set 1, 2, 3,or 4 word(s) mode
321 BuffMode // set traversal mode, normal, swing, or onetime
324 DAC_C1_REG(dac0_ptr) = regval;
325 #ifdef DAC_TWO_CHANNEL
326 DAC_C1_REG(dac1_ptr) = regval;
327 #endif
329 regval = BuffInitPos | BuffUpLimit;
330 DAC_C2_REG(dac0_ptr) = regval;
331 #ifdef DAC_TWO_CHANNEL
332 DAC_C2_REG(dac1_ptr) = regval;
333 #endif
335 /* pdb0 init */
336 SIM_SCGC6 |= SIM_SCGC6_PDB_MASK ; // SCGC6 is at address 0x4004_803Ch
337 PDB0_SC = PDB_SC_PDBEN_MASK; // enable PDB module
341 static void dacc_deinit(struct snd_pcm_runtime *runtime)
343 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *)runtime->private_data;
344 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
345 DAC_MemMapPtr dac0_ptr = dma_data->dac0_base;
346 DAC_MemMapPtr dac1_ptr = dma_data->dac1_base;
347 uint32_t regval;
349 /* move to trigger stop */
350 regval = DAC_DISABLE;
351 DAC_C0_REG(dac0_ptr) = regval;
352 DAC_C0_REG(dac1_ptr) = regval;
353 #if 1
355 #if (MQX_CPU == PSP_CPU_MK70F120M)
356 _bsp_int_disable(INT_DMA0_DMA16);
357 #elif (MQX_CPU == PSP_CPU_MK60D100M )
358 _bsp_int_disable(INT_DMA0);
359 #else
360 #error "only support K70,K60 chip"
361 #endif
363 SIM_SCGC2 &= (~ (SIM_SCGC2_DAC0_MASK | SIM_SCGC2_DAC1_MASK)); // Disable clock to enable DAC0 ,DAC1
365 /* pdb0 deinit */
366 PDB0_SC &= (~PDB_SC_PDBEN_MASK); // enable PDB module
367 SIM_SCGC6 &= (~SIM_SCGC6_PDB_MASK) ; // SCGC6 is at address 0x4004_803Ch
368 #endif
371 static int dac_set_clock(int frame_rate)
373 /* sampleRates[source] = samplerate; */
374 uint32_t regval;
375 // Effective after writting PDBSC_DACTOE = 1 (1/48000KHz) * 1088 = 0.0226757369614512ms (44100)
376 #if (MQX_CPU == PSP_CPU_MK70F120M)
377 regval = 60000000/frame_rate;
378 #elif (MQX_CPU == PSP_CPU_MK60D100M )
379 regval = 48000000/frame_rate;
380 #else
381 #error "only support K70,K60 chip"
382 #endif
383 regval -= 1;
385 PDB0_DACINT0 = regval;
386 #ifdef DAC_TWO_CHANNEL
387 PDB0_DACINT1 = regval;
388 #endif
390 PDB0_SC |= PDB_SC_LDOK_MASK; // load the value assigned to PDBDACINTV to register
391 PDB0_SC |= PDB_SC_TRGSEL(15); // software trigger
392 PDB0_SC |= PDB_SC_CONT_MASK ; // CONT mode
393 // move to trigger start
394 //PDB0_DACINTC0 |= PDB_DACINTC0_TOE_MASK ;
395 //PDB0_DACINTC1 |= PDB_DACINTC0_TOE_MASK ;
397 return 0;
400 static int dma_tcd_list_init(struct snd_pcm_runtime *runtime,unsigned int ch)
402 int i = 0;
403 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *) runtime->private_data;
404 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
406 uint32_t length = bytes_fifo_aligned(iprtd->period_bytes, dma_data->fifo_aligned_bits, runtime->sample_phy_bits) / 2;
407 uint32_t tcd_lists_cnt = iprtd->periods;
409 DMA_TCD_t * tcd_list;
410 unsigned int dac_base_ptr;
412 if(tcd_lists_cnt > MAX_TCD_LISTS)
413 return -1;
415 if(ch == DMA_CHANNEL_DAC0) {
416 tcd_list = tcd_list0;
417 dac_base_ptr = ((unsigned int) (DAC0_BASE_PTR ));
419 else if(ch == DMA_CHANNEL_DAC1) {
420 tcd_list = tcd_list1;
421 dac_base_ptr = ((unsigned int) (DAC1_BASE_PTR ));
423 else
424 return -1;
426 os_memset(tcd_list, 0, sizeof(tcd_list));
428 for(; i < tcd_lists_cnt; i++){
429 tcd_list[i].SOFF = 1;
430 #ifdef DAM16WORD_TWICE
431 tcd_list[i].ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(1) | DMA_ATTR_DMOD(5);
432 #else
433 // 8bits for D&S, 16bytes wrapped, ie, 4 address bit changing allowed.
434 tcd_list[i].ATTR = DMA_ATTR_SSIZE(0) | DMA_ATTR_DSIZE(0) /*| DMA_ATTR_DMOD(5)*/;
435 #endif
436 // We use scatter-gether mode, and the SADDR will be reloaded, but this field still need be set properly.
437 tcd_list[i].SLAST = 0;// -AUDIO_DMA_BUFFER_SIZE;
438 #ifdef DAM16WORD_TWICE
439 tcd_list[i].DOFF = 2;
440 tcd_list[i].DADDR = ((unsigned int) (dac_base_ptr )) + 16;
441 #else
442 tcd_list[i].DOFF = 1;
443 tcd_list[i].DADDR = (unsigned int) dac_base_ptr; // DAC DATA buffer base address
444 #endif
446 #ifdef DAM16WORD_TWICE
447 tcd_list[i].NBYTES_MLOFFNO = DMA_NBYTES_MLOFFNO_NBYTES(DAC_BUFFER_SIZE);
448 #else
449 /*tcd_list[i].NBYTES_MLOFFNO = DMA_NBYTES_MLOFFNO_NBYTES(DAC_BUFFER_SIZE);*/
450 tcd_list[i].NBYTES_MLOFFYES = (DMA_NBYTES_MLOFFYES_DMLOE_MASK |
451 DMA_NBYTES_MLOFFYES_MLOFF(-DAC_BUFFER_SIZE) | // Destination address minus 32 ever minor_loop
452 DMA_NBYTES_MLOFFYES_NBYTES(DAC_BUFFER_SIZE)); // 32 bytes per minor-loop
453 #endif
455 if(ch == DMA_CHANNEL_DAC0)
456 tcd_list[i].SADDR = (uint_32)(((uint8_t *)iprtd->buf) + (i * length));
457 else /* always dac1 */
458 tcd_list[i].SADDR = (uint_32)(((uint8_t *)iprtd->buf + runtime->dma_bytes / 2) + (i * length));
461 tcd_list[i].CITER_ELINKNO = length/DAC_BUFFER_SIZE;
462 tcd_list[i].BITER_ELINKNO = length/DAC_BUFFER_SIZE;
464 tcd_list[i].CSR = (DMA_CSR_ESG_MASK /*| DMA_CSR_INTMAJOR_MASK*/);
465 if(ch == DMA_CHANNEL_DAC0)
466 tcd_list[i].CSR |= DMA_CSR_INTMAJOR_MASK;
468 if (i != (tcd_lists_cnt - 1))
469 tcd_list[i].DLAST_SGA = (unsigned int)(&tcd_list[i+1]);
472 tcd_list[tcd_lists_cnt - 1].DLAST_SGA = (unsigned int)(&tcd_list[0]);
474 dma_load_td_chain(ch, &tcd_list[0]);
476 return 0;
479 static void dma_load_td_chain(unsigned int ch, DMA_TCD_p tcd_list)
481 DMA_SADDR(ch) = tcd_list->SADDR;
482 DMA_SOFF(ch) = tcd_list->SOFF;
483 DMA_ATTR(ch) = tcd_list->ATTR;
484 DMA_NBYTES_MLOFFYES(ch) = tcd_list->NBYTES_MLOFFYES;
485 DMA_SLAST(ch) = tcd_list->SLAST;
487 DMA_DADDR(ch) = tcd_list->DADDR;
488 DMA_DOFF(ch) = tcd_list->DOFF;
489 DMA_CITER_ELINKNO(ch) = tcd_list->CITER_ELINKNO;
490 DMA_DLAST_SGA(ch) = tcd_list->DLAST_SGA;
491 DMA_CSR(ch) = tcd_list->CSR;
492 DMA_BITER_ELINKNO(ch) = tcd_list->BITER_ELINKNO;
495 static inline void dma_start_channel(unsigned int ch)
497 DMA_SERQ = DMA_SERQ_SERQ(ch);
498 //DMA_CSR_REG(DMA_BASE_PTR,ch) = (/*DMA_CSR_DREQ_MASK |*/ DMA_CSR_INTMAJOR_MASK);
501 static void dma_stop_channel(unsigned int ch)
503 do {
504 DMA_CERQ_REG(DMA_BASE_PTR) = ch;
505 } while(DMA_CSR_REG(DMA_BASE_PTR, ch) & DMA_CSR_ACTIVE_MASK);
508 static inline uint_16 dac_format_in_data (struct snd_pcm_runtime *runtime, uint16_t *inbuf)
510 uint_16 retval = 0;
511 #if 1
512 int32_t temp = (int16_t)inbuf[0];
513 temp *= (2 * 90); /* vol = 50 (min 1- max 256) */;
514 temp = temp >> (5 + 8);
515 temp += 2048;
516 temp &= 0xfff; // XXX dither the sample
518 retval = temp;
519 #else
520 int32_t temp = *((int16_t *)(input));
521 temp += 32768;
522 temp = temp >> 4;
524 temp &= 0xfff; // XXX dither the sample
525 retval = temp;
526 #endif
528 return ((unsigned short) retval);
532 /* codec and ssi preinit set params */
533 static int preinit_params(struct snd_pcm_runtime *runtime,
534 struct snd_pcm_params *params)
536 uint32_t intf_format;
537 int ret;
538 unsigned int channels = params->channels;
540 /* open and init clock */
541 return 0;
544 /* mute the dac */
545 static int dac_digital_mute(int mute)
547 // todo
548 return 0;
551 static int codec_pcm_interface_params(struct snd_pcm_runtime *runtime,
552 struct snd_pcm_params *params)
554 if (runtime->stream != SNDRV_PCM_STREAM_PLAYBACK )
555 return -1;
556 if (params->format != SNDRV_PCM_FORMAT_S16_LE)
557 return -1;
559 return dac_set_clock(params->rate);
562 static int cpu_interface_params(struct snd_pcm_runtime *runtime,
563 struct snd_pcm_params *params)
565 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *)runtime->private_data;
566 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
567 int data_bits = 0;
568 unsigned int channels = params->channels;
570 return 0;
573 static void dac_edma_interrupt_handler(void * data)
575 audio_dma_irq(data,DMA_CHANNEL_DAC0);
576 DMA_CINT_REG(DMA_BASE_PTR) = DMA_CHANNEL_DAC0;
577 DMA_CDNE_REG(DMA_BASE_PTR) = DMA_CHANNEL_DAC0;
580 void dma_mux(unsigned int channel, unsigned int request)
582 #if (MQX_CPU == PSP_CPU_MK70F120M)
583 DMAMUX0_CHCFG(channel) = (DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(request));
584 #elif (MQX_CPU == PSP_CPU_MK60D100M )
585 DMAMUX_CHCFG(channel) |= (DMAMUX_CHCFG_ENBL_MASK | DMAMUX_CHCFG_SOURCE(request));
586 #else
587 #error "only support K70,K60 chip"
588 #endif
592 static int dma_pcm_params(struct snd_pcm_runtime *runtime,
593 struct snd_pcm_params *params)
595 int ret;
596 unsigned int bits;
597 snd_pcm_uframes_t frames;
598 unsigned int buffer_bytes_adjusted = 0;
599 unsigned int buffer_bytes = 0;
601 struct sco_pcm_runtime_data *iprtd = (struct sco_pcm_runtime_data *) runtime->private_data;
602 struct soc_dma_data * dma_data = (struct soc_dma_data *)iprtd->dma_data;
604 if(!sys_dma_inited) {
605 sys_dma_inited = 1;
606 printf("dma inited\n");
607 #if (MQX_CPU == PSP_CPU_MK70F120M)
608 SIM_SCGC6 |= SIM_SCGC6_DMAMUX0_MASK;
609 #elif (MQX_CPU == PSP_CPU_MK60D100M )
610 SIM_SCGC6 |= SIM_SCGC6_DMAMUX_MASK; // Enable clocks to the DMA Mux.
611 #else
612 #error "only support K70,K60 chip"
613 #endif
614 SIM_SCGC7 |= SIM_SCGC7_DMA_MASK; // Enable clocks to the eDMA module.
615 dma_mux(DMA_CHANNEL_DAC0, DMA_REQUEST_DAC0);
616 #ifdef DAC_TWO_CHANNEL
617 dma_mux(DMA_CHANNEL_DAC1, DMA_REQUEST_DAC1);
618 #endif
620 // clear flags
621 DMA_CEEI |= DMA_CEEI_CAEE_MASK;
622 DMA_CERQ |= DMA_CERQ_CAER_MASK;
623 DMA_CDNE |= DMA_CDNE_CADN_MASK;
624 DMA_CERR |= DMA_CERR_CAEI_MASK;
625 DMA_CINT |= DMA_CINT_CAIR_MASK;
627 DMA_EEI = 0x00;
630 For proper operation, writes to the CR register must be
631 performed only when the DMA channels are inactive; that is,
632 when TCDn_CSR[ACTIVE] bits are cleared
634 // enable minor off mode
636 #if (MQX_CPU == PSP_CPU_MK70F120M)
637 DMA_CR|= DMA_CR_EDBG_MASK;
638 #elif (MQX_CPU == PSP_CPU_MK60D100M)
639 //enable minor off mode
640 DMA_CR = DMA_CR_EMLM_MASK;
641 #else
642 #error "only support K70,K60 chip"
643 #endif
647 /* Default params */
648 dma_data->fifo_aligned_bits = FIFO_BITS_ALIGNED;
649 dma_data->fifo_align_type = FIFO_BITS_ENDTYPES;
650 runtime->sample_aligned_bits = dma_data->fifo_aligned_bits; /* sample_aligned_bits usb by pcm.c */
652 if (params->periods != 0) { /* params periods high priority */
653 runtime->buffer_size = runtime->period_size * params->periods;
654 runtime->periods = params->periods;
655 buffer_bytes = frames_to_bytes(runtime,runtime->buffer_size);
657 else if(params->buffer_bytes != 0) {
658 runtime->buffer_size = bytes_to_frames(runtime,params->buffer_bytes);
659 runtime->periods = runtime->buffer_size /runtime->period_size;
660 buffer_bytes = params->buffer_bytes;
662 else {
663 pr_err("err: both params periods and buffer_bytes all zero!\n");
664 return -1;
667 buffer_bytes_adjusted = bytes_fifo_aligned(buffer_bytes,
668 dma_data->fifo_aligned_bits, runtime->sample_phy_bits); /* div runtime->sample_phy_bits is error !*/
670 /* runtime->avail_min = runtime->period_size; */
672 if ((runtime->periods > MAX_PERIODS) || (runtime->periods < MIN_PERIODS)) {
673 pr_err("err: periods number\n");
674 return -1;
677 runtime->boundary = runtime->buffer_size;
678 while (runtime->boundary * 2 <= LONG_MAX - runtime->buffer_size)
679 runtime->boundary *= 2;
681 if (params->start_threshold == THRESHOLD_BOUNDARY)
682 runtime->start_threshold = runtime->boundary;
683 else
684 runtime->start_threshold = params->start_threshold;
686 if (params->stop_threshold == THRESHOLD_BOUNDARY)
687 runtime->stop_threshold = runtime->boundary;
688 else
689 runtime->stop_threshold = params->stop_threshold;
691 if (params->stop_threshold == THRESHOLD_BOUNDARY)
692 runtime->silence_threshold = runtime->boundary;
693 else
694 runtime->silence_threshold = params->silence_threshold;
695 runtime->silence_size = params->silence_size; /* runtime->period_size */
697 runtime->dma_area = PCM_mem_alloc_zero(buffer_bytes_adjusted);
698 if(!runtime->dma_area) {
699 printf("alloc dma buffer failed\n");
700 return -1;
702 pr_debug("dma buffer size : snd need = %d,soc allocate %d\n",buffer_bytes,buffer_bytes_adjusted);
705 iprtd->size = frames_to_bytes(runtime, runtime->buffer_size);
706 iprtd->periods = runtime->periods;
707 iprtd->period_bytes = frames_to_bytes(runtime,runtime->period_size);
708 iprtd->offset = 0;
709 iprtd->period_time = (HZ * runtime->period_size + (runtime->rate -1)) /runtime->rate;
710 iprtd->buf = (unsigned int *)runtime->dma_area;
713 runtime->dma_bytes = frames_to_bytes(runtime,runtime->buffer_size) * runtime->sample_aligned_bits / runtime->sample_phy_bits;
715 dma_tcd_list_init(runtime,DMA_CHANNEL_DAC0);
716 #ifdef DAC_TWO_CHANNEL
717 dma_tcd_list_init(runtime,DMA_CHANNEL_DAC1);
718 #endif
720 /* only install DAC0 dma marjor interrput */
721 #if (MQX_CPU == PSP_CPU_MK70F120M)
722 _int_install_isr(INT_DMA0_DMA16, dac_edma_interrupt_handler, (void *)(runtime));
723 _bsp_int_init(INT_DMA0_DMA16, DMA_INTR_PRIO, 0, TRUE);
724 #elif (MQX_CPU == PSP_CPU_MK60D100M )
725 _int_install_isr(INT_DMA0, dac_edma_interrupt_handler, (void *)(runtime));
726 _bsp_int_init(INT_DMA0, DMA_INTR_PRIO, 0, TRUE);
727 #else
728 #error "only support K70,K60 chip"
729 #endif
732 /* snd_pcm_prepare(runtime); */ /* drop and setup then prepare !!! ( prepare always reset all pointer !!! ) */
734 return 0;
737 #define MAX_SAMPLE_SKEW 50
738 static int audsamplerate;
739 static int audsampleratebase = 44100;
741 void dac_skew_sample_rate(int skew)
743 uint32_t regval;
744 audsamplerate += skew;
745 if (audsamplerate - audsampleratebase > MAX_SAMPLE_SKEW)
746 audsamplerate = audsampleratebase + MAX_SAMPLE_SKEW;
747 if (audsampleratebase - audsamplerate > MAX_SAMPLE_SKEW)
748 audsamplerate = audsampleratebase - MAX_SAMPLE_SKEW;
750 //dac_set_clock(audsamplerate);
751 #if (MQX_CPU == PSP_CPU_MK70F120M)
752 regval = 60000000/audsamplerate;
753 #elif (MQX_CPU == PSP_CPU_MK60D100M )
754 regval = 48000000/audsamplerate;
755 #else
756 #error "only support K70,K60 chip"
757 #endif
759 regval -= 1;
760 #ifdef DAC_TWO_CHANNEL
761 PDB0_DACINT1 = regval;
762 #endif
763 PDB0_DACINT0 = regval;
764 PDB0_SC |= PDB_SC_LDOK_MASK;
767 int sco_pcm_vol_down()
769 return 0;
772 int sco_pcm_vol_up()
774 return 0;
777 #endif // KINETS_K60DAC