19 |
|
|
20 |
/* hardware definition */ |
/* hardware definition */ |
21 |
static snd_pcm_hardware_t snd_vortex_playback_hw_adb = { |
static snd_pcm_hardware_t snd_vortex_playback_hw_adb = { |
22 |
.info = (SNDRV_PCM_INFO_MMAP | |
.info = (SNDRV_PCM_INFO_MMAP | SNDRV_PCM_INFO_RESUME| SNDRV_PCM_INFO_PAUSE| |
23 |
SNDRV_PCM_INFO_INTERLEAVED | |
SNDRV_PCM_INFO_INTERLEAVED | |
24 |
SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), |
SNDRV_PCM_INFO_MMAP_VALID), // | SNDRV_PCM_INFO_BLOCK_TRANSFER), |
25 |
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 | |
.formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U8 | |
26 |
SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW, |
SNDRV_PCM_FMTBIT_MU_LAW | SNDRV_PCM_FMTBIT_A_LAW, |
27 |
.rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, |
.rates = SNDRV_PCM_RATE_8000_48000 | SNDRV_PCM_RATE_CONTINUOUS, |
101 |
// Alloc buffer memory. |
// Alloc buffer memory. |
102 |
err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(hw_params)); |
103 |
if (err < 0) { |
if (err < 0) { |
104 |
printk("Vortex: pcm page alloc failed!\n"); |
printk(KERN_ERR "Vortex: pcm page alloc failed!\n"); |
105 |
return err; |
return err; |
106 |
} |
} |
107 |
|
|
108 |
printk("Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params), |
printk(KERN_INFO "Vortex: periods %d, period_bytes %d, channels = %d\n", params_periods(hw_params), |
109 |
params_period_bytes(hw_params), params_channels(hw_params)); |
params_period_bytes(hw_params), params_channels(hw_params)); |
110 |
|
|
111 |
// Make audio routes and config buffer DMA. |
// Make audio routes and config buffer DMA. |
112 |
if (substream->pcm == chip->pcm_adb) { |
if (substream->pcm == chip->pcm_adb) { |
113 |
vortex_adbdma_setbuffers(chip, dma->dma, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params)); |
vortex_adbdma_setbuffers(chip, dma->dma, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params)); |
114 |
//if (dma->nr_ch) |
//if (dma->nr_ch != 0) |
115 |
vortex_adb_waveroute(chip, dma->dma, 0); |
vortex_adb_waveroute(chip, dma->dma, 0); |
116 |
//if (params_channels(hw_params)) |
//if (params_channels(hw_params) != 0) |
117 |
vortex_adb_waveroute(chip, dma->dma, params_channels(hw_params)); |
vortex_adb_waveroute(chip, dma->dma, params_channels(hw_params)); |
118 |
} else { |
} else { |
119 |
vortex_wtdma_setbuffers(chip, dma->dma, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params)); |
vortex_wtdma_setbuffers(chip, dma->dma, (u32)(runtime->dma_addr), params_period_bytes(hw_params), params_periods(hw_params)); |
144 |
vortex_t *chip = snd_pcm_substream_chip(substream); |
vortex_t *chip = snd_pcm_substream_chip(substream); |
145 |
snd_pcm_runtime_t *runtime = substream->runtime; |
snd_pcm_runtime_t *runtime = substream->runtime; |
146 |
dma_t *dma = (dma_t*)substream->runtime->private_data; |
dma_t *dma = (dma_t*)substream->runtime->private_data; |
147 |
int fmt, i, cvrt; |
int fmt, dir; |
148 |
|
|
149 |
// set up the hardware with the current configuration. |
// set up the hardware with the current configuration. |
150 |
|
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
151 |
|
dir = 1; |
152 |
|
else |
153 |
|
dir = 0; |
154 |
fmt = vortex_alsafmt_aspfmt(runtime->format); |
fmt = vortex_alsafmt_aspfmt(runtime->format); |
155 |
if (substream->pcm == chip->pcm_adb) { |
if (substream->pcm == chip->pcm_adb) { |
156 |
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
vortex_adbdma_setmode(chip, dma->dma, 1, dir, fmt, 0/*?*/, 0); |
|
i = 1; |
|
|
cvrt = SRC_RATIO(runtime->rate); |
|
|
} else { |
|
|
i = 0; |
|
|
cvrt = SRC_RATIO2(runtime->rate); |
|
|
} |
|
|
vortex_adbdma_setmode(chip, dma->dma, 1, i/*direction*/, fmt, 1/*?*/, 0); |
|
|
for (i=0; i<(chip->dma_adb[dma->dma].nr_ch); i++) |
|
|
vortex_src_change_convratio(chip, i+(dma->dma*2), cvrt); |
|
|
|
|
157 |
vortex_adbdma_setstartbuffer(chip, dma->dma, 0); |
vortex_adbdma_setstartbuffer(chip, dma->dma, 0); |
158 |
|
vortex_adb_setsrc(chip, dma->dma, runtime->rate, dir); |
159 |
} else { |
} else { |
160 |
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) |
vortex_wtdma_setmode(chip, dma->dma, 1, dir, fmt, 0, 0); |
161 |
i = 1; |
// FIXME: Set rate (i guess using vortex_wt_writereg() somehow). |
|
else |
|
|
i = 0; |
|
|
vortex_wtdma_setmode(chip, dma->dma, 1, i, fmt, 1, 0); |
|
|
// FIXME: Set rate (if possible). |
|
162 |
vortex_wtdma_setstartbuffer(chip, dma->dma, 0); |
vortex_wtdma_setstartbuffer(chip, dma->dma, 0); |
163 |
} |
} |
164 |
return 0; |
return 0; |
172 |
switch (cmd) { |
switch (cmd) { |
173 |
case SNDRV_PCM_TRIGGER_START: |
case SNDRV_PCM_TRIGGER_START: |
174 |
// do something to start the PCM engine |
// do something to start the PCM engine |
175 |
printk("vortex: start %d\n", dma->dma); |
printk(KERN_INFO "vortex: start %d\n", dma->dma); |
176 |
if (substream->pcm == chip->pcm_adb) { |
if (substream->pcm == chip->pcm_adb) { |
177 |
dma->fifo_enabled = 1; |
dma->fifo_enabled = 1; |
178 |
vortex_adbdma_startfifo(chip, dma->dma); |
vortex_adbdma_startfifo(chip, dma->dma); |
183 |
break; |
break; |
184 |
case SNDRV_PCM_TRIGGER_STOP: |
case SNDRV_PCM_TRIGGER_STOP: |
185 |
// do something to stop the PCM engine |
// do something to stop the PCM engine |
186 |
printk("vortex: stop %d\n", dma->dma); |
printk(KERN_INFO "vortex: stop %d\n", dma->dma); |
187 |
if (substream->pcm == chip->pcm_adb) { |
if (substream->pcm == chip->pcm_adb) { |
188 |
dma->fifo_enabled = 0; |
dma->fifo_enabled = 0; |
189 |
vortex_adbdma_stopfifo(chip, dma->dma); |
vortex_adbdma_stopfifo(chip, dma->dma); |
194 |
} |
} |
195 |
break; |
break; |
196 |
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
case SNDRV_PCM_TRIGGER_PAUSE_PUSH: |
197 |
|
printk(KERN_INFO "vortex: pause %d\n", dma->dma); |
198 |
if (substream->pcm == chip->pcm_adb) |
if (substream->pcm == chip->pcm_adb) |
199 |
vortex_adbdma_pausefifo(chip, dma->dma); |
vortex_adbdma_pausefifo(chip, dma->dma); |
200 |
else |
else |
201 |
vortex_wtdma_pausefifo(chip, dma->dma); |
vortex_wtdma_pausefifo(chip, dma->dma); |
202 |
break; |
break; |
203 |
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: |
204 |
if (substream->pcm == chip->pcm_adb) |
printk(KERN_INFO "vortex: resume %d\n", dma->dma); |
205 |
|
if (substream->pcm == chip->pcm_adb) |
206 |
vortex_adbdma_resumefifo(chip, dma->dma); |
vortex_adbdma_resumefifo(chip, dma->dma); |
207 |
else |
else |
208 |
vortex_wtdma_resumefifo(chip, dma->dma); |
vortex_wtdma_resumefifo(chip, dma->dma); |
224 |
current_ptr = vortex_adbdma_getlinearpos(chip, dma->dma); |
current_ptr = vortex_adbdma_getlinearpos(chip, dma->dma); |
225 |
else |
else |
226 |
current_ptr = vortex_wtdma_getlinearpos(chip, dma->dma); |
current_ptr = vortex_wtdma_getlinearpos(chip, dma->dma); |
227 |
//printk("vortex: pointer = 0x%x\n", current_ptr); |
//printk(KERN_INFO "vortex: pointer = 0x%x\n", current_ptr); |
228 |
spin_unlock(chip->lock); |
spin_unlock(chip->lock); |
229 |
return (bytes_to_frames(substream->runtime, current_ptr)); |
return (bytes_to_frames(substream->runtime, current_ptr)); |
230 |
} |
} |